Compare two typical types in Java?

I have the following method:

public <U, V> boolean isEqual(List<U> a, List<V> b) { // check if U == V } 

I want to check if the tags U and V the same classes.

+5
source share
6 answers

You cannot do this because of erasing styles , it's that simple.

Consider the following:

 public static void main(String[] args) { List<? extends Number> l1 = Arrays.asList(1L, 2, 3L); List<? extends Number> l2 = Arrays.asList(1); isEqual(l1, l2); } public static <U, V> boolean isEqual(List<U> a, List<V> b) { // is U == V here? } 

Here U == V ? l1 contains instances of Long and Integer , but l2 contains one instance of Integer .


I assume from your comment:

The first condition must be that their type is the same

what you need is the only type of U In this case, use the following signature:

 public static <U> boolean isEqual(List<U> a, List<U> b) { } 

nor will the above code compile anymore.


What you can also do is add 2 parameters that take classes:

 public static <U, V> boolean isEqual(List<U> a, List<V> b, Class<U> uClass, Class<V> vClass) { if (!uClass.equals(vClass)) { // classes are different } } 

In this case, you can print a message if the specified classes do not match.

+7
source

If you create your own class, you may require that the Class<T> be included in the constructor, as shown here

Example:

 public class SomeClass<T> { private final Class<T> clazz; public SomeClass(Class<T> clazz) { this.clazz = clazz; } public Class<T> getParam() { return clazz; } } 

Now you can call SomeClass#getParam() to get the declared type.


There is also a way to do this with reflection.


All of this suggests that you have to make weird workarounds to this because of Type Erasure . Basically, at runtime, Java sees all generics as Object , so when compiling your List may be List<Integer> or List<Boolean> , but at run time they are both List<Object> .

+2
source

If you are trying to compare the contents of two lists, you should not perform type comparisons yourself. Instead, you should do this:

  public static <U, V> boolean isEqual(List<U> a, List<V> b) { if (a.size() != b.size()) return false; for (int i = 0; i < a.size(); i++) if (!a.get(i).equals(b.get(i))) return false; return true; } 

Thus, you rely on types U and V to be able to handle equals () correctly. Here are some guidelines for implementing equals (): http://www.javaworld.com/article/2072762/java-app-dev/object-equality.html

What I suppose you want to do is quickly return in case the types are different. But with the implementation that I gave you, you will get the same behavior - you will return to the first iteration.

+1
source

Don't rely on

 a.getClass().equals(b.getClass()) 

This is not true, it will check if both types have ArrayList and not String, Integer, etc.

Try it only

 a.get(0).getClass().equals(b.get(0).getClass()) 

Make sure you check for a null state, otherwise you will encounter a NullPointerException here.

0
source

I think you would like to check if == b is in place of U == V. In this case, you need to write your own comparison method to compare an instance of class U and V.

0
source

Assuming a and b are not null, not null,

 a.get(0).getClass().equals(b.get(0).getClass()) 

gotta do the trick.

-1
source

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


All Articles