Java 列表过滤并查找第一个/最后一个查找



我有一个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);

但是,我确实知道这是一个低效的解决方案,因为我们循环了三次。有人可以帮助我以更高性能的方式解决它吗?

任何帮助将不胜感激,谢谢:)

我建议按标签将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"检查点。

您可以先收集到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"

最新更新