使用流时,是否有更智能的方法可以在不使用 new ArrayList() 和 return lst 行的情况下创建不同的列表?
public static List<BeanLevel> sniff(List<BeanTask> tasks) {
List<BeanLevel> lst = new ArrayList();
tasks.stream().map(task-> task.level).forEach(level-> {
if (lst.stream().filter(distinctLevel-> level.id == distinctLevel.id).findAny().isPresent()) {
return;
}
lst.add(level);
});
return lst;
}
解决方案1
一旦将 equals 函数绑定到对象/Bean 中,您就可以在流中使用不同的函数。
public class BeanLevel {
public long id;
@Override
public int hashCode() {
int hash = 7;
hash = 43 * hash + (int) (this.id ^ (this.id >>> 32));
return hash;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
BeanLevel other = (BeanLevel) obj;
return Objects.equals(id, other.id);
}
}
public static List<BeanLevel> sniff(List<BeanTask> tasks) {
return tasks.stream().map(task-> task.level).distinct().toList();
}
解决方案2
如在此处所示,无需覆盖 Bean/Object 中的任何内容,您就可以区分对象。
public static <T> Predicate<T> distinctByKey(Function<? super T, ?> keyExtractor) {
Set<Object> seen = ConcurrentHashMap.newKeySet();
return t -> seen.add(keyExtractor.apply(t));
}
public static List<BeanLevel> sniff(List<BeanTask> tasks) {
return tasks.stream().map(task-> task.level).filter(distinctByKey(BeanLevel::getId)).toList();
}