Фильтр списков Java и найти сначала / найти последним - PullRequest
3 голосов
/ 21 марта 2019

У меня есть список объектов Java. Атрибуты объекта:

public class CheckPoint {
    private String message;
    private String tag;
}

Теперь я хочу найти фильтр списка по тегу и получить первый / последний элемент.

Например: возможные значения тегов: A, B, C. Для тегов со значением A - я хочу последний элемент, а B - я хочу первый элемент, C - первый элемент

Текущее решение:

CheckPoint inTransitCheckPoint = checkPointsList.stream().filter(c -> c.getTag().equals("A")).reduce((first, second) -> second).orElse(null);

CheckPoint useCheckPoint = checkPointsList.stream().filter(c -> c.getTag().equals("B")).findFirst.orElse(null);

CheckPoint typeCheckPoint = checkPointsList.stream().filter(c -> c.getTag().equals("C")).findFirst.orElse(null);

Однако я понимаю, что это неэффективное решение, так как мы делаем цикл трижды. Может ли кто-нибудь помочь мне решить эту проблему более продуктивно?

Любая помощь будет оценена, спасибо:)

Ответы [ 2 ]

2 голосов
/ 21 марта 2019

Я предлагаю сгруппировать тег checkPointList по тегу Map<String, LinkedList<CheckPoint>>:

Map<String, LinkedList<CheckPoint>> map = new HashMap<>();
map.put("A", new LinkedList<>());
map.put("B", new LinkedList<>());
map.put("C", new LinkedList<>());

for(CheckPoint c : checkPointList) {
    map.computeIfAbsent(c.getTag(), ignored -> new LinkedList<>()).add(c);
}

Связанный список является удобным помощником, поскольку он позволяет вам напрямую получить первый или последний элемент (и, если он отсутствует)возвращает null):

CheckPoint A = map.get("A").pollLast();
CheckPoint B = map.get("B").pollFirst();
CheckPoint C = map.get("C").pollFirst();

Или вы можете просто использовать это еще проще for-loop:

CheckPoint a = null, b = null, c = null;
for (CheckPoint checkPoint : checkPointList) {
    String tag = checkPoint.getTag();
    if ("A".equals(tag) && a == null) {
        a = checkPoint;
    } else if("B".equals(tag)){
        b = checkPoint;
    } else if("C".equals(tag)){
        c = checkPoint;
    }
}

Переменные для "B" и "C" являютсявсегда перезаписывается последним значением, тогда как для a будет выбрана только первая "A" контрольная точка.

2 голосов
/ 21 марта 2019

Вы можете сначала собрать до Map, например:

Map<String, List<CheckPoint>> map = 
       checkPointsList.stream()
                      .collect(Collectors.groupingBy(CheckPoint::getTag));

Optional.ofNullable(map.get("A"))
        .orElse(Collection.emptyList())
        .reduce((left, right) -> right)
        .orElse(null);
// same for "B" and "C"
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...