我有一个要求,我需要从列表中获取不同的元素,并且不同的键字段是可变的。我试图在distinctByKey 中传递变量参数,但它不起作用。这就是我需要做的 -
class Pojo {
final String name;
final Integer price;
final String ref1;
public Pojo(final String name, final Integer price, final String ref1) {
this.name = name;
this.price = price;
this.ref1 = ref1;
}
public String getName() {
return name;
}
public Integer getPrice() {
return price;
}
public String getRef1() {
return ref1;
}
以下是代码,我尝试通过将distinctByKey参数作为参数传递来从列表中获取不同的值
class Test1 {
public static <T> Predicate<T> distinctByKey(Function<? super T, Object> keyExtractor) {
Map<Object, Boolean> seen = new ConcurrentHashMap<>();
return t -> seen.putIfAbsent(keyExtractor.apply(t), Boolean.TRUE) == null;
}
private static List<Pojo> getList() {
return Arrays.asList(
new Pojo("123", 100, "A"),
new Pojo("123", 100, "B"),
new Pojo("123", 100, "C"),
new Pojo("456", 200, "D")
);
}
private static List<Pojo> ff1 = new ArrayList<>();
public static void main(String[] args) {
ff1.add(getList().get(0));
ff1.add(getList().get(1));
ff1.add(getList().get(2));
ff1.add(getList().get(3));
String key1 = "p.getName() + p.getPrice()" ;
List<Pojo> f1 =ff1.stream()
.filter(distinctByKey(p -> key1))
.collect(Collectors.toList());
System.out.println(f1);
目的是如果我想通过 ref1 进行区分,我可以动态地做到这一点。请建议我如何实现这一点?
如果您不想使用反射,则必须传递一个与实际 getter 一起使用的密钥提取器。这样做的先决条件是对象的类型已知,这已经适用于您的情况。
List<Pojo> f1 = ff1.stream()
.filter(distinctByKey(p -> p.getName() + p.getPrice())) // key is a String
.collect(Collectors.toList());
f1.forEach(System.out::println);
Pojo(name=123, price=100, ref1=A) Pojo(name=456, price=200, ref1=D)
第一个找到的且不同的
name
和 price
组合出现在列表中,除非您重新实现 distinctByKey
方法。