当前位置: 首页 > 知识库问答 >
问题:

在Java8[duplicate]中从基于属性的对象列表中删除重复项

樊熠彤
2023-03-14

我正试图从基于某些属性的对象列表中删除重复项。

我们能用一种简单的方法使用Java8吗

List<Employee> employee

我们是否可以根据员工的id属性删除其中的重复项。我看到过从String的arraylist中删除重复字符串的帖子。

共有1个答案

贺自明
2023-03-14

您可以从列表中获取一个流,并将其放入树集中,您可以从该树集中提供一个用于唯一比较id的自定义比较器。

然后,如果您真的需要一个列表,您可以将这个集合放回一个ArrayList中。

import static java.util.Comparator.comparingInt;
import static java.util.stream.Collectors.collectingAndThen;
import static java.util.stream.Collectors.toCollection;

...
List<Employee> unique = employee.stream()
                                .collect(collectingAndThen(toCollection(() -> new TreeSet<>(comparingInt(Employee::getId))),
                                                           ArrayList::new));

举个例子:

List<Employee> employee = Arrays.asList(new Employee(1, "John"), new Employee(1, "Bob"), new Employee(2, "Alice"));

它将输出:

[Employee{id=1, name='John'}, Employee{id=2, name='Alice'}]

另一种方法是使用包装器包装雇员,并以其ID为基础使用equals和hashcode方法:

class WrapperEmployee {
    private Employee e;

    public WrapperEmployee(Employee e) {
        this.e = e;
    }

    public Employee unwrap() {
        return this.e;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        WrapperEmployee that = (WrapperEmployee) o;
        return Objects.equals(e.getId(), that.e.getId());
    }

    @Override
    public int hashCode() {
        return Objects.hash(e.getId());
    }
}
List<Employee> unique = employee.stream()
                                .map(WrapperEmployee::new)
                                .distinct()
                                .map(WrapperEmployee::unwrap)
                                .collect(Collectors.toList());

事实上,我认为您可以通过提供一个函数来进行比较,从而使这个包装器泛型化:

public class Wrapper<T, U> {
    private T t;
    private Function<T, U> equalityFunction;

    public Wrapper(T t, Function<T, U> equalityFunction) {
        this.t = t;
        this.equalityFunction = equalityFunction;
    }

    public T unwrap() {
        return this.t;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        @SuppressWarnings("unchecked")
        Wrapper<T, U> that = (Wrapper<T, U>) o;
        return Objects.equals(equalityFunction.apply(this.t), that.equalityFunction.apply(that.t));
    }

    @Override
    public int hashCode() {
        return Objects.hash(equalityFunction.apply(this.t));
    }
}

映射将是:

.map(e -> new Wrapper<>(e, Employee::getId))
 类似资料:
  • 名单中有重名的;对于这些,只想保留最后一个。 例如。如果列表有三个项目,并且第一个和第三个项目都有值为“abc”的“name”,那么结果列表应该只包含来自原始列表的第二个和第三个项目。

  • 问题基于https://stackoverflow.com/A/29671501/2517622 有办法吗?

  • 我下面有一个类,想删除包含同名的重复人,如何使用Java8 Lambda,预计列表包含下面的p1、p3。

  • 问题内容: 试图从基于某些属性的对象列表中删除重复项。 我们可以使用Java 8以简单的方式做到吗 我们可以根据员工的财产从中删除重复项吗?我看到过从字符串arraylist中删除重复字符串的帖子。 问题答案: 你可以从获取流并将其放入其中,从中提供一个唯一比较ID的自定义比较器。 然后,如果你确实需要一个列表,则可以将该集合放回到ArrayList中。 给出示例: 它将输出: 另一个想法可能是使

  • 我有一个这样定义的类: 现在我有一个项目对象列表,现在我想找到所有项目的总价。在Java8中我们如何做到这一点? 如果列表是简单的整数,那么我们在这里给出了解决方案--如何用java流求和整数列表?

  • 如何根据属性值从数组中删除所有对象? 在上面的代码中,它只删除一个对象。如何删除所有if匹配项?