Store comparator objects in an array

I defined 4 comparators for my object as follows:

public static Comparator<mObject> comp0 = new Comparator<mObject>() { @Override public int compare(mObject l, mObject r) { ...compare } }; public static Comparator<mObject> comp1 = new Comparator<mObject>() { @Override public int compare(mObject l, mObject r) { ...compare } }; public static Comparator<mObject> comp2 = new Comparator<mObject>() { @Override public int compare(mObject l, mObject r) { ...compare } }; public static Comparator<mObject> comp4 = new Comparator<mObject>() { @Override public int compare(mObject l, mObject r) { ...compare } }; 

Now I want to create an array with 4 comparators, for example:

 public final static Comparator<mObject>[] Object_comparators = { comp0, comp1, comp2, comp3}; 

but Eclipse underlines everything between {..} as if it were a mistake. Why exactly, and how can I fix it?

+3
source share
2 answers

You cannot create an array of classes with a parameterized generic type.

If you don't mind losing security, you can do this:

 Comparator[] list = new Comparator[4]; 

But my preferred strategy would be to use List :

 List<Comparator<mObject>> list = Arrays.asList(comp0, comp1, comp2, comp3); 
+9
source

As Mark Elliot said, you cannot use the generics type in arrays. This is due to type erasure, while arrays have their type known at runtime. Due to type erasure, the generic type is never known at run time. This means that generics are just useful during compilation, and that with some tricks you can embed Animal objects in a List<Comparator>

Btw, you cannot declare an anonymous array to be created without specifying an array type, since there is no type erasure for an array type.

Therefore, creating an array using common types is not allowed and may lead to unexpected behavior.

Think about it: if you create an array of cars (Car []), you can apply it to the object []. This does not mean that you can put objects in this array, since the type of the array is still known at runtime. You will get an ArrayStoreException if you try to put the dog in this array.


Now, what if we created an array Car<Ferrari>[] ? You can still apply it to the [] object. It works like an array Car [], except when you include it in Object [] , you can put objects of type Car<Renault> at runtime, since the generic type is unknown!


I think Java prevents us from this behavior.

But you can still use an array of generics links !!!

 public static void main(String[] args) { Comparator<String> NORMAL = new Comparator<String>() { @Override public int compare(String s, String s1) { return s.compareTo(s1); } }; Comparator<String> REVERSE = new Comparator<String>() { @Override public int compare(String s, String s1) { return - s.compareTo(s1); } }; Comparator<String>[] comparators = new Comparator[] {NORMAL,REVERSE}; List<String> strings = Arrays.asList("f","d","c","a","e","b"); TreeSet<String> normalSet = new TreeSet<String>(comparators[0]); normalSet.addAll(strings); for ( String s : normalSet ) { System.out.println("normal : " + s); } TreeSet<String> reverseSet = new TreeSet<String>(comparators[1]); reverseSet.addAll(strings); for ( String s : reverseSet ) { System.out.println("reverse : " + s); } } 

Outputs:

 normal : a normal : b normal : c normal : d normal : e normal : f reverse : f reverse : e reverse : d reverse : c reverse : b reverse : a 

So you can use arrays with generics, but Java seems to be stopping you from doing something.

I assume that initially the contract with the array could be something like this:

If you create an array of type X, you NEVER NEVER put something in it that IS-NOT-AN X. If you try, you will get an ArrayStoreException

Thus, creating arrays with creating generics will result in the following rule, for example:

If you create an array of type X<Y> , you NEVER can put anything that is NOT-NOT-AND X. If you try, you will get an ArrayStoreException. But you can add objects X<Y> and X<Z> !


As my previous code shows, we CANNOT create arrays using generics, but we can create arrays without generics and use them as an array with generics.

 Comparator<String>[] comparators = new Comparator[] {NORMAL,REVERSE}; 

I guess this is somehow a way for Java to tell us: β€œIf you know what you are doing, then it’s good that you can do it”

+2
source

Source: https://habr.com/ru/post/911735/


All Articles