Java lists filter and find first/find last

The-Proton-Resurgence :

I have a java list of objects. The object attributes are:

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

Now, I want to find the filter the list based on tag and get first/last element.

For eg: Possible tag values: A, B, C. For tags with value A - I want the last element, and B - I want first element, C - first element

Current Solution:

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);

However, I do understand this is an inefficient solution since we are looping thrice. Can someone help me solve it in a more performant way?

Any help will be appreciated, thanks :)

Lino :

I suggest grouping the checkPointList by tag into a 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);
}

The linked list is a handy helper because it allows you to directly get the first or last element (and if absent returns null):

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

Or you can just use this even easier 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;
    }
}

The variables for "B" and "C" are always overwritten with the last value, whereas for a only the first "A" checkpoint will be chosen.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=92189&siteId=1
Recommended