0

I want to merge two ArrayList of objects without duplicate records using Java 8. I can not modify hashcode and equals method of a class, but I can identify duplicate using class parameters.

Pseudo Code

 public class Students {
         int id;  // Use to identify duplicates
         String name;
          //getters , setters and constructor code
      }

    
     public class Start {
         public static void main(String[] args) {
 List<Students> list1= new ArrayList<>();
        list1.add( new Students(1,"Josh"));
        list1.add( new Students(2, "Jacob"));
        list1.add(new Students(3,"Jane"));

        List<Students> list2= new ArrayList<>();
        list2.add( new Students(1, "Josh"));
        list2.add(new Students(4,"Jorge"));

        // merge two list without duplicate 

       Stream.of(list1,list2).flatMap(List :: Stream ) // now how can I filter duplicates ?
    }
         }
     
    
     
sar
  • 1,277
  • 3
  • 21
  • 48
  • 1
    You could override `equals` and `hashCode`. Then you `addAll` both lists into a `Set`. Then you create a new list from that `Set`. – akuzminykh Jul 17 '20 at 00:49

2 Answers2

0

You can filter using HashSet#add, as it returns true if the element was added since it did not originally exist in the Set and false otherwise.

final Set<Integer> ids = new HashSet<>();
final List<Students> unique = Stream.of(list1, list2).flatMap(List::stream)
       .filter(s -> ids.add(s.getId()))
                .collect(Collectors.toList());
unique.forEach(s -> System.out.println(s.getId() + "-" + s.getName()));

Demo

Unmitigated
  • 76,500
  • 11
  • 62
  • 80
0

Also by using predicate:

 public static <T> Predicate<T> distinctById(
        Function<? super T, ?> property) {
    Map<Object, Boolean> p = new ConcurrentHashMap<>();
    return t -> p.putIfAbsent(property.apply(t), Boolean.TRUE) == null;
}

Then you can filter the stream:

 Stream.of(list1, list2)
 .flatMap(List::stream)
 .filter(distinctById(s -> s.getId()))
 .collect(Collectors.toList());
iperezmel78
  • 415
  • 5
  • 20