Determine the difference between the two lists

In java, suppose I have 2 lists

List<Object1> list1 List<Object2> list2 object1.getName(); returns a String object2.getName(); return a String 

is there any way to compare names and get the difference in two lists

these 2 objects are defined in a third-party library, and I cannot override the equals and compareto methods

I stand for a collection of googles Guava collections or collective collections

but Sets.symmetricDifference(Set1, Set2) ask to transfer 2, even I juse Sets.newHashSet (lis1) and Sets.newHashSet (lis2) to create two sets but still they have a difference type of objects in sets.

or in the public CollectionUtils.disjunction(lis1, list2) lists should still contain the same type of object

without making 2 expensive for loops, is there any other way?

+5
source share
3 answers

First, we will build two maps: one for each list, matching names with objects. Then we iterate over the differences between the key sets, processing whatever type of object this name has. Maps allow you to avoid scanning in a list that searches for an object with this name. (When using Map, not Multimap, I rely on the respondent’s comment for another answer that the names in each list are unique. If you are still using Java 7, replace the method reference with the implementation of the function.)

 Map<String, Object1> map1 = Maps.uniqueIndex(list1, Object1::getName); Map<String, Object2> map2 = Maps.uniqueIndex(list2, Object1::getName); for (String name : Sets.difference(map1.keySet(), map2.keySet())) processObject1(map1.get(name)); for (String name : Sets.difference(map2.keySet(), map1.keySet())) processObject2(map2.get(name)); 

If all you want to do is collect lists or sets of objects in only one list, processObject1 and processObject2 can simply add objects to collections.

uniqueIndex iteration order is the input iterable, and difference returns a SetView with the same iteration order as its first argument, so you can process the objects in the order they appear in the input lists, if that order is relevant to your problem.


Java 8 threads provide basically the same functionality:

 Map<String, Object1> map1 = list1.stream().collect(Collectors.toMap(Function.identity(), Object1::getName)); Map<String, Object2> map2 = list2.stream().collect(Collectors.toMap(Function.identity(), Object2::getName)); map1.keySet().stream().filter(n -> !map2.keySet().contains(n)).map(map1::get).forEachOrdered(o1 -> processObject1(o1)); map2.keySet().stream().filter(n -> !map1.keySet().contains(n)).map(map2::get).forEachOrdered(o2 -> processObject1(o2)); 

Again, you can replace the forEachOrdered call with collect(Collectors.toList()) if you just want to collect the objects.

+1
source

Using Guava, try this. It works for me β†’

 Multisets.difference(multiset1,multiset2); 

How to convert ArrayList to Multiset.

  List x = new ArrayList(); x.add(3);..... Multiset newX = HashMultiset.create(); newX.addAll(x); 
0
source

First you need to translate your lists into String based lists:

 private static final class FromObject1ToName implements Function<Object1, String> { @Override public String apply(Object1 input) { return input.name; } } 

The same conversion should be performed for Object2

Then convert the input list:

  Collection<String> transformed = Collections2.transform(list1, new FromObject1ToName()); 

// list1 is List on Object1

Then create a multiset:

  Multiset<String> multiset1 = HashMultiset.create(); multiset1.addAll(transformed); 

Then just do:

  Multisets.difference(multiset1, multiset2) // multiset1 is from Object1 and multiset2 is from Object2 

It will give you a difference and how many times it is different

If you only need to know the differences, then do the same conversion, then load the collection of strings into Set adn, then do Sets.symmetricDifference

0
source

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


All Articles