【问题标题】:Select distinct fields of an ArrayList of Class X选择 X 类 ArrayList 的不同字段
【发布时间】:2019-04-17 09:40:36
【问题描述】:

我有一个 X 类的 ArrayList。

ArrayList<X> items = new ArrayList();

X 类包含多个字段,全部为字符串类型。 (id、描述、品牌……)

如果我想获得这个类的 ArrayList,它只包含给定字段的不同值,我该怎么办?

在实践中:

如何获得包含所有品牌但没有重复的 X 类的 ArrayList? (获取items中的所有品牌,但两次没有品牌)

或者有没有更好/更有效的方法来获取品牌列表?

\e: 我不使用 Java8。

希望这不会太混乱。

【问题讨论】:

标签: java performance arraylist


【解决方案1】:
 items.stream()
            .collect(Collectors.groupingBy(X::getBrand))   // group your items by brand
            .values().stream()                            // stream map values
            .map(e->e.get(0))                            // for each brand get first element in brand list 
            .collect(Collectors.toList());

如果你不能使用 java8/streams

    Map<String,List<X>> map = new HashMap<>();
    for(X item : items){
        if(!map.containsKey(item.getBrand())){
            map.put(item.getBrand(), new ArrayList<>());
        }else{
            map.get(item.getBrand()).add(item);
        }
    }
    List<X> result = new ArrayList<>();
    for(Map.Entry<String,List<X>> e : map.entrySet()){
        result.add(e.getValue().get(0));
    }

【讨论】:

    【解决方案2】:

    使用java.util.Set,根据定义,它不允许重复值。

    Set<String> s = new HashSet<>();
    for(X x : items) {
        s.add(x.getField());
    }
    
    // "s" now contains all distinct "field"
    

    应该有一个使用 lambda 和流的代码版本。但是IMO这种简单的代码不需要它

    【讨论】:

    • OP 希望列表包含 X 对象,而不是字符串。
    【解决方案3】:

    1) 如果您想在某个领域获得独特的结果,请使用 distinctbykey 中的实用方法 filter

    public static <T> Predicate<T> distinctByKey(Function<? super T, Object> keyExtractor) {
        Map<Object, Boolean> map = new ConcurrentHashMap<>();
        return t -> map.putIfAbsent(keyExtractor.apply(t), Boolean.TRUE) == null;
      }
    
    ArrayList<X> items = new ArrayList();
    items = items
      .stream()
      .filter( distinctByKey(x -> x.uniqueFiled()) ) // pass field of X object on basis of you want unique objects
      .collect(Collectors.toList());
    

    2) 还有另一种方法可以在列表中不重复。 Override equalshash 类的 X 函数,您必须在其中比较 Brand 字段,然后使用 stream 的 distinct 方法,它将通过调用您的 equals 和 @ 返回不同的对象列表987654331@函数。

    ArrayList<X> items = new ArrayList();
    items = items
      .stream()
      .distinct()
      .collect(Collectors.toList());
    

    3) 如果你实现了equalshash 函数。然后只需从List 创建一个SetSet 具有独特的元素,十个再次从 Set 创建 List

    ArrayList<X> items = new ArrayList();
    Set<X> set = new HashSet<X>(items); // Now set has unique elements
    items = set.stream().collect(Collectors.toList()); // list have unique elemets too
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-03-16
      • 2019-10-15
      • 1970-01-01
      • 1970-01-01
      • 2013-04-22
      • 1970-01-01
      • 2021-03-24
      相关资源
      最近更新 更多