小编典典
你可以从获取流List并将其放入TreeSet其中,从中提供一个唯一比较ID的自定义比较器。
然后,如果你确实需要一个列表,则可以将该集合放回到ArrayList中。
import static java.util.Comparator.comparingInt;
import static java.util.stream.Collectors.collectingAndThen;
import static java.util.stream.Collectors.toCollection;
...
List unique = employee.stream()
.collect(collectingAndThen(toCollection(() -> new TreeSet<>(comparingInt(Employee::getId))),
ArrayList::new));
给出示例:
List 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());
}
}
然后包装每个实例,调用distinct(),解开它们并将结果收集在列表中。
List unique = employee.stream()
.map(WrapperEmployee::new)
.distinct()
.map(WrapperEmployee::unwrap)
.collect(Collectors.toList());
实际上,我认为你可以通过提供进行比较的函数来使此包装器通用:
class Wrapper {
private T t;
private Function equalityFunction;
public Wrapper(T t, Function 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 that = (Wrapper) 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))
2020-03-17