带有可变参数的 Java StreamdistinctByKey 过滤器

问题描述 投票:0回答:1

我有一个要求,我需要从列表中获取不同的元素,并且不同的键字段是可变的。我试图在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 进行区分,我可以动态地做到这一点。请建议我如何实现这一点?

filter lambda java-stream predicate
1个回答
0
投票

如果您不想使用反射,则必须传递一个与实际 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
方法。

© www.soinside.com 2019 - 2024. All rights reserved.