Java8使用stream查找重复元素的方法示例
作者:好奇的菜鸟
Java 8 是一个非常成功的版本,这个版本新增的Stream,配合同版本出现的Lambda ,给我们操作集合(Collection)提供了极大的便利,Stream流是JDK8新增的成员,本文给大家介绍了Java8使用stream查找重复元素的方法示例,需要的朋友可以参考下
一、查重方法
public static <E> List<E> getDuplicateElements(List<E> list) { return list.stream() // list 对应的 Stream .collect(Collectors.toMap(e -> e, e -> 1, (a, b) -> a + b)) // 获得元素出现频率的 Map,键为元素,值为元素出现的次数 .entrySet().stream() // 所有 entry 对应的 Stream .filter(entry -> entry.getValue() > 1) // 过滤出元素出现次数大于 1 的 entry .map(entry -> entry.getKey()) // 获得 entry 的键(重复元素)对应的 Stream .collect(Collectors.toList()); // 转化为 List }
二、测试
public static void main(String[] args) throws Exception { List<String> list = Arrays.asList("a", "b", "c", "d", "a", "a", "d", "d","c","b","e","f"); List<String> duplicateElements = getDuplicateElements(list); System.out.println("list 中重复的元素:" + duplicateElements); }
运行结果
list 中重复的元素:[a, b, c, d]
拓展知识
Java8通过stream对列表去重:
1、Stream的distinct()方法
distinct()方法是Java 8中Stream提供的方法。返回的是由该流中不同元素组成的流。distinct()方法使用hashCode()和equals()方法来获取不同的元素。因此,需要去重的类必须实现hashCode()和equals()方法。也就是说,可以通过重写定制的hashCode()和equals()方法来达到特殊需求的去重。
distinct()方法声明:
Stream<T> distinct();
String列表去重
List<String> stringList = new ArrayList<String>() {{ add("A"); add("A"); add("B"); add("B"); add("C"); }}; List<String> newStringList = stringList.stream().distinct().collect(Collectors.toList()); for (String s : newStringList) { System.out.println(s); }
实体类列表去重
@Test public void test2() throws JsonProcessingException { String s = "[\n" + "\t{\n" + " \"stuNo\": \"001\",\n" + " \"name\": \"Tom\"\n" + " }, {\n" + " \"stuNo\": \"002\",\n" + " \"name\": \"Mike\"\n" + " }, {\n" + " \"stuNo\": \"001\",\n" + " \"name\": \"Tom\"\n" + " }\n" + "]"; ObjectMapper objectMapper = new ObjectMapper(); List<Student> studentList = objectMapper.readValue(s, new TypeReference<List<Student>>() { }); List<Student> collect= studentList.stream().distinct().collect(Collectors.toList()); System.out.println(objectMapper.writeValueAsString(collect)); }
List<Object> 根据Object中某个属性去重
方式一:Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>
@Test public void test3() throws JsonProcessingException { String s = "[\n" + "\t{\n" + " \"stuNo\": \"001\",\n" + " \"name\": \"Tom\"\n" + " }, {\n" + " \"stuNo\": \"002\",\n" + " \"name\": \"Mike\"\n" + " }, {\n" + " \"stuNo\": \"001\",\n" + " \"name\": \"Tom\"\n" + " }\n" + "]"; ObjectMapper objectMapper = new ObjectMapper(); List<Student> studentList = objectMapper.readValue(s, new TypeReference<List<Student>>() { }); List<Student> collect= studentList.stream().collect( Collectors.collectingAndThen( Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(Student::getName))), ArrayList::new) ); System.out.println(objectMapper.writeValueAsString(collect)); }
方式二:通过filter()方法
创建一个方法作为Stream.filter()的参数,其返回值为Predicate类型,原理就是通过判断一个元素能否加入到set中。
public static void main(String[] args) { Person p = new Person(); p.setName("1"); Person p2 = new Person(); p2.setName("2"); Person p3 = new Person(); p3.setName("1"); List<Person> ps = new ArrayList<>(); ps.add(p); ps.add(p2); ps.add(p3); List<Person> collect = ps.stream().filter(distinctByKey(new Function<Person, Object>() { @Override public Object apply(Person person) { return person.getName(); } })).collect(Collectors.toList()); System.out.println(JSON.toJSONString(collect)); } /** * 此方法能根据不为空的字段值去重 * 要求person.getName()不能为空 */ private static <T> Predicate<T> distinctByKey(Function<? super T, ?> keyExtractor) { Set<Object> seen = ConcurrentHashMap.newKeySet(); return t -> seen.add(keyExtractor.apply(t)); } /** * 当字段值不为空的字段值去重,为空的数据不过滤 * person.getName()的值可为空 * * @return 返回属性值为空的数据+属性值不为空且去重的数据之和 */ private static <T> Predicate<T> distinctByKey(Function<? super T, ?> keyExtractor) { Set<Object> seen = ConcurrentHashMap.newKeySet(); Predicate<T> predicate = new Predicate<T>() { @Override public boolean test(T t) { Object o = keyExtractor.apply(t); if (ObjectUtils.isEmpty(o)) { return true; } return seen.add(o); } }; }
到此这篇关于Java8使用stream查找重复元素的方法示例的文章就介绍到这了,更多相关Java8 stream重复元素内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!