有这么一个需求,需要将从数据库查出来的数据进行去重。
开发人员并没搞清楚用户是想按照对象去重还是要按照对象的属性去重。用户是希望按照对象的某个属性去重。因为有一列是时间按照对象去重相当于没去重。导致前台数据重复
第132行被注释掉的是按照对象去重
为了修复这个bug需要按照对象的属性(glassID)去重。
List中对象去重
** 重写对象的equals()
方法和hashCode()
方法
Person p1 = new Person(1l, "jack"); Person p2 = new Person(3l, "jack chou"); Person p3 = new Person(2l, "tom"); Person p4 = new Person(4l, "hanson"); Person p5 = new Person(5l, "胶布虫"); List<Person> persons = Arrays.asList(p1, p2, p3, p4, p5, p5, p1, p2, p2); List<Person> personList = new ArrayList<>(); // 去重 persons.stream().forEach( p -> { if (!personList.contains(p)) { personList.add(p); } } ); System.out.println(personList);
List 的contains()
方法底层实现使用对象的equals方法去比较的,其实重写equals()
就好,但重写了equals最好将hashCode也重写了。
List 根据对象的属性去重
通过Comparator比较器,比较对象属性,相同就返回0,达到过滤的目的。
public static List<WppTegMeasureF> removeDupliById(List<WppTegMeasureF> wppTegMeasureF) { Set<WppTegMeasureF> personSet = new TreeSet<>((o1, o2) -> o1.getGlassId().compareTo(o2.getGlassId())); personSet.addAll(wppTegMeasureF); return new ArrayList<>(personSet); }
google的 List 根据对象的属性去重
import static java.util.Comparator.comparingLong; import static java.util.stream.Collectors.collectingAndThen; import static java.util.stream.Collectors.toCollection; // 根据id去重 List<Person> unique = persons.stream().collect( collectingAndThen( toCollection(() -> new TreeSet<>(comparingLong(Person::getId))), ArrayList::new) );
另外一种写法
public static <T> Predicate<T> distinctByKey(Function<? super T, Object> keyExtractor) { Map<Object, Boolean> map = new ConcurrentHashMap<>(); return t -> map.putIfAbsent(keyExtractor.apply(t), Boolean.TRUE) == null; } // remove duplicate persons.stream().filter(distinctByKey(p -> p.getId())).forEach(p -> System.out.println(p));