Java8通过stream对列表去重

时间:2025-02-24 21:25:01

1、Stream的distinct()方法

distinct()方法是Java 8中Stream提供的方法。返回的是由该流中不同元素组成的流。distinct()方法使用hashCode()和equals()方法来获取不同的元素。因此,需要去重的类必须实现hashCode()和equals()方法。也就是说,可以通过重写定制的hashCode()和equals()方法来达到特殊需求的去重。

distinct()方法声明:

Stream<T> distinct();

1、String列表去重

List<String> stringList = new ArrayList<String>() {{
            add("A");
            add("A");
            add("B");
            add("B");
            add("C");
        }};
        List<String> newStringList = ().distinct().collect(());
        for (String s : newStringList) {
            (s);
        }

2、实体类列表去重

@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 = (s, new TypeReference<List<Student>>() {
        });
        List<Student>  collect= ().distinct().collect(());
        ((collect));

    }

3、List<Object> 根据Object中某个属性去重

3.1 方式一:((() -> new TreeSet<>((Student::getName))), ArrayList::new)

  @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 = (s, new TypeReference<List<Student>>() {
        });
        List<Student>  collect= ().collect(
                (
                        (() -> new TreeSet<>((Student::getName))), ArrayList::new)
        );
        ((collect));

    }

3.2、方式二:通过filter()方法

创建一个方法作为()的参数,其返回值为Predicate类型,原理就是通过判断一个元素能否加入到set中。

public static void main(String[] args) {
        Person p = new Person();
        ("1");

        Person p2 = new Person();
        ("2");
        Person p3 = new Person();
        ("1");
        List<Person> ps = new ArrayList<>();
        (p);
        (p2);
        (p3);
       
        List<Person> collect = ().filter(distinctByKey(new Function<Person, Object>() {
            @Override
            public Object apply(Person person) {
                return ();
            }
        })).collect(());
        ((collect));
    }

/**
 * 此方法能根据不为空的字段值去重
 * 要求()不能为空
 */
private static <T> Predicate<T> distinctByKey(Function<? super T, ?> keyExtractor) {
    Set<Object> seen = ();
    return t -> ((t));
}

/**
 * 当字段值不为空的字段值去重,为空的数据不过滤
 * ()的值可为空
 *
 * @return 返回属性值为空的数据+属性值不为空且去重的数据之和
 */
private static <T> Predicate<T> distinctByKey(Function<? super T, ?> keyExtractor) {
        Set<Object> seen = ();
        Predicate<T> predicate = new Predicate<T>() {
            @Override
            public boolean test(T t) {
                Object o = (t);
                if ((o)) {
                    return true;
                }
                return (o);
            }
        };
}