Reputation: 6099
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:
O[] array = (O[]) new Object[n];
but that doesn't compile.Object[] array = new Object[n];
and do an (O) cast every time I request something from the array, but this is way too slowArray.newInstance(Class<O> type, int n);
, with O o;
and type=o.class
but it complains that type
is now of type Class<CAP#1>
instead of type Class<O>
, whatever CAP#1 means...How should I do this properly in Java, with optimal execution speed in mind?
Upvotes: 3
Views: 214
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
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
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
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