前言
在工作中,相信很多开发同学会遇到一个需求:对一个队列进行去重操作。平时注重积累,有沉淀的同学,可能就会很熟练的使用stream().distinct()
等等方法; 而其他同学(包括我),此时往往需要面向谷歌编程,施展 ctrl+c & ctrl+v 大法,这次解决了,下次依旧如此,周而复始,生生不息,子子孙孙无穷尽也。。。
额。。。扯远了。言归正传,前面说到对队列去重,可以使用stream().dinstinct()
。但是,当想根据队列中对象的某一个属性来进行去重的话,stream().distinct()
的局限性就体现出来了。
因此,我封装了一个方法,实现对队列中的对象整体或者对象中的某一个属性值进行去重,并做了一定的单元测试。
方法说明:
List<T> toDistinctList
:传入需要去重的队列,可以是 ArrayList
,LinkedList
,Vector
,如果传入的队列类型非以上三种,则默认返回 ArrayList
;
Function<? super T, ?> objectProperty
: 接收一个对象,返回一个对象,比如传入: student -> student.getName()
或者用 lambda 表达式 Student::getName
。当为空时,则表示根据整个对象进行去重;不为空时,则表示根据对象中某一个传入的属性进行去重
代码
方法代码:
/***@MethodName:distinct*@Description:队列去重,支持对对象整体去重(此时objectProperty为空),也支持对对象内部某个属性去重;*支持对ArrayList,LinkedList以及Vector队列进行去重操作,默认返回ArrayList*@Param:toDistinctList待去重队列*@Param:objectProperty队列中对象的属性*@Return:java.util.List<T>*@Exception:*@author:arkMon*@date:2021/2/611:31*/publicstatic<T>List<T>distinct(List<T>toDistinctList,Function<?superT,?>objectProperty){if(CollectionUtils.isEmpty(toDistinctList)){if(toDistinctListinstanceofArrayList){returnnewArrayList<>();}if(toDistinctListinstanceofLinkedList){returnnewLinkedList<>();}if(toDistinctListinstanceofVector){returnnewVector<>();}}if(toDistinctListinstanceofLinkedList){if(objectProperty==null){returntoDistinctList.stream().distinct().collect(Collectors.toCollection(LinkedList::new));}returntoDistinctList.stream().filter(distinctByKey(objectProperty)).collect(Collectors.toCollection(LinkedList::new));}if(toDistinctListinstanceofVector){if(objectProperty==null){returntoDistinctList.stream().distinct().collect(Collectors.toCollection(Vector::new));}returntoDistinctList.stream().filter(distinctByKey(objectProperty)).collect(Collectors.toCollection(Vector::new));}if(objectProperty==null){returntoDistinctList.stream().distinct().collect(Collectors.toList());}returntoDistinctList.stream().filter(distinctByKey(objectProperty)).collect(Collectors.toList());}publicstatic<T>List<T>distinct(List<T>toDistinctList){returndistinct(toDistinctList,null);}privatestatic<T>Predicate<T>distinctByKey(Function<?superT,?>objectProperty){Set<Object>seen=ConcurrentHashMap.newKeySet();returnt->seen.add(objectProperty.apply(t));}
单元测试:
publicclassListUtilTest{List<Student>students=newArrayList<>();List<Student>studentsDistinct=newArrayList<>();List<Student>studentsDistinctByName=newArrayList<>();List<String>former=newArrayList<>();List<String>formerOnly=newArrayList<>();List<String>latter=newArrayList<>();List<String>latterOnly=newArrayList<>();List<String>common=newArrayList<>();List<String>sampleinkedList=newLinkedList<>();List<String>expectLinkedList=newLinkedList<>();List<String>sampleVector=newVector<>();List<String>expectVector=newVector<>();@Beforepublicvoidbefore(){Studentstudent0=Student.builder().age(10).clazz(4).name("tom").build();Studentstudent1=Student.builder().age(10).clazz(4).name("tom").build();Studentstudent2=Student.builder().age(11).clazz(5).name("tom").build();Studentstudent3=Student.builder().age(11).clazz(6).name("jerry").build();students.add(student0);students.add(student1);students.add(student2);students.add(student3);studentsDistinct.add(student0);studentsDistinct.add(student2);studentsDistinct.add(student3);studentsDistinctByName.add(student0);studentsDistinctByName.add(student3);former=Arrays.asList("a","b","c");formerOnly=Arrays.asList("a","b");latter=Arrays.asList("c","d","e");latterOnly=Arrays.asList("d","e");common=Arrays.asList("c");sampleinkedList.add("a");sampleinkedList.add("b");sampleinkedList.add("c");sampleinkedList.add("c");sampleinkedList.add("d");sampleinkedList.add("e");sampleinkedList.add("c");expectLinkedList.add("a");expectLinkedList.add("b");expectLinkedList.add("c");expectLinkedList.add("d");expectLinkedList.add("e");sampleVector.add("a");sampleVector.add("b");sampleVector.add("c");sampleVector.add("c");sampleVector.add("d");sampleVector.add("e");sampleVector.add("c");expectVector.add("a");expectVector.add("b");expectVector.add("c");expectVector.add("d");expectVector.add("e");}@Testpublicvoiddistinct(){List<String>list0=Arrays.asList("a","b","c","c","b","a");List<String>actual0=ListUtil.distinct(list0);List<String>expect0=Arrays.asList("a","b","c");assertEquals(expect0,actual0);List<Integer>list1=Arrays.asList(1,2,3,3,2,1);List<Integer>actual1=ListUtil.distinct(list1);List<Integer>expect1=Arrays.asList(1,2,3);assertEquals(expect1,actual1);List<Double>list2=Arrays.asList(1.0d,2.0d,3.0d,3.0d,2.0d,1.0d);List<Double>actual2=ListUtil.distinct(list2);List<Double>expect2=Arrays.asList(1.0d,2.0d,3.0d);assertEquals(expect2,actual2);List<Float>list3=Arrays.asList(1.0f,2.0f,3.0f,3.0f,2.0f,1.0f);List<Float>actual3=ListUtil.distinct(list3);List<Float>expect3=Arrays.asList(1.0f,2.0f,3.0f);assertEquals(expect3,actual3);ArrayList<Object>list4=newArrayList<>();List<Object>actual4=ListUtil.distinct(list4);List<Object>expect4=newArrayList<>();assertEquals(expect4.getClass(),actual4.getClass());LinkedList<Object>list5=newLinkedList<>();List<Object>actual5=ListUtil.distinct(list5);List<Object>expect5=newLinkedList<>();assertEquals(expect5.getClass(),actual5.getClass());Vector<Object>list6=newVector<>();List<Object>actual6=ListUtil.distinct(list6);List<Object>expect6=newVector<>();assertEquals(expect6.getClass(),actual6.getClass());List<Student>actual7=ListUtil.distinct(students);assertEquals(studentsDistinct,actual7);List<Student>actual8=ListUtil.distinct(students,Student::getName);assertEquals(studentsDistinctByName,actual8);List<String>actual9=ListUtil.distinct(sampleinkedList);assertEquals(expectLinkedList,actual9);assertEquals(expectLinkedList.getClass(),actual9.getClass());List<String>actual10=ListUtil.distinct(sampleVector);assertEquals(expectVector,actual10);assertEquals(expectVector.getClass(),actual10.getClass());}}
TODO项
根据对象的任意个属性值进行去重处理