Выберите отдельные поля ArrayList класса X - PullRequest
0 голосов
/ 17 апреля 2019

У меня есть ArrayList класса X.

ArrayList<X> items = new ArrayList();

Класс X содержит несколько полей, все из которых имеют тип string.(id, описание, бренд, ...)

Так что же мне делать, если я хочу получить ArrayList этого класса, который содержит только отдельные значения для данного поля?

На практике:

Как я могу получить ArrayList класса X, который содержит все бренды, но не содержит дубликатов?(получить все бренды в items, но без бренда дважды)

Или есть какой-нибудь лучший / более эффективный способ получить только список брендов?

\ e: я не используюJava8.

Надеюсь, это не слишком запутанно.

Ответы [ 3 ]

1 голос
/ 17 апреля 2019
 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));
    }
0 голосов
/ 17 апреля 2019

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 equals и hash функция класса X, в которой вы должны сравнить поле Brand, а затем использовать отдельный метод stream, он вернет список различных объектов, вызвав ваши equals и hash функция.

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

3) Если вы реализуете функции equals и hash. затем просто создайте Set из List. Set имеет уникальные элементы, и десять снова создают List из этого Set.

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
0 голосов
/ 17 апреля 2019

Используйте java.util.Set, который по определению не допускает дублирования значений.

Set<String> s = new HashSet<>();
for(X x : items) {
    s.add(x.getField());
}

// "s" now contains all distinct "field"

должна существовать версия этого кода, использующая лямбды и потоки.Но ИМО такой простой код не требует

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...