user1111929
user1111929

Reputation: 6099

Java how to: Generic array creation from class with generic?

I have a class FirstClass<O> and a class SecondClass<O>, and I want to make an O[] in SecondClass<O> inside a routine which is called from FirstClass<O>, where O is a generic class parameter. I fail to find how to do this.

I need an O[] specifically (and not ArrayList<O> or similar) because I need to get elements from it very often inside the body of a loop, and it matters for the execution time of my algorithm.

So I would want something along these lines.

public class FirstClass<O> {
    void someRoutine(n and other params) {
        //Do some stuff
        SecondClass<O> = new SecondClass(n, possibly_other_params);
        //Do some stuff
    }
}

and

public class SecondClass<O> {
    O[] myArray;
    SecondClass<O>(int n, possibly_other_params) {
        //Here the constructor that creates an O[n]
    }
}

Some methods I found on the web, but do not work for my case:

How should I do this properly in Java, with optimal execution speed in mind?

Upvotes: 3

Views: 214

Answers (4)

Paul Bellora
Paul Bellora

Reputation: 55213

Here is the source code for ArrayList.set:

public E set(int index, E element) {
    rangeCheck(index);

    E oldValue = elementData(index);
    elementData[index] = element;
    return oldValue;
}

Granted, it does an additional lookup to get the old element, which you don't care about, but this is random access we're talking about (read: O(1) time). Just use ArrayList unless you have hard numbers to show it's slowing you down.

Upvotes: 0

newacct
newacct

Reputation: 122429

Use O[] array = (O[]) new Object[n]; but this requires an (O) cast every time I request something from the array, so this is way too slow

What? The whole point of type O[] is that you don't need an (O) cast when getting things out of it

Upvotes: 1

user1623834
user1623834

Reputation:

Java's handling of generics is in pretty rough shape but you can accomplish something close to what you want if you are prepared to make small adjustments. Please see:

public class FirstClass<O> {
    Class<O> type;

    public static <O> FirstClass<O> create(Class<O> type) {
        return new FirstClass<O>(type);
    }

    public FirstClass(Class<O> type) {
        this.type = type;
    }

    public void routine(int size /*, other params */ ) {
        SecondClass<O> instance = new SecondClass<O>(type, size);
    }
}

public class SecondClass<O> {
    public O[] array;

    @SuppressWarnings("unchecked")
    public SecondClass(Class<O> type,int size) {
        array = (O[])Array.newInstance(type,size);
    }
}

And a use case:

FirstClass<Integer> instance = FirstClass.create(Integer.class);
instance.routine(110);

This is just a rough example although I am sure you could accomplish something similar without having to use this approach.

Upvotes: 3

ziesemer
ziesemer

Reputation: 28687

Repeating my comment from above to hopefully mark this question as answered:

Have you actually profiled this? Is the casting actually what is causing your performance concerns? Given that generics in Java are erased at runtime, I don't see an easy work-around here to get it working as you're expecting. I think you'll be better off trying to re-visit your expected API, then trying to get Java's generics to work they way you want.

Upvotes: 0

Related Questions