0

I have a situation similar to the follows:

List<ObjectA> all = repository.findAll(Sort.by(Sort.Direction.ASC, "status"));

This find a list of object with three possible states: OPEN, CLOSED, PROGRAMMED

Now I must return a List that shows to the user the last PROGRAMMED object, the first OPEN object and all closed objects. I have writing something like that:

ObjectA programmed = all.stream().filter(isPROGRAMMED()).reduce((x,y) -> y).orElse(null);
ObjectA open = all.stream().filter(isOPEN()).findFirst().get();
List<ObjectA> closed = all.stream().filter(isCLOSED()).collect(Collectors.toList());

isOPEN(), isPROGRAMMED() and isCLOSED() are Predicate I have written as follows:

private static Predicate<ObjectA> isPROGRAMMED() {
    return x -> x.getStatus().equals(Stato.PROGRAMMED);
}

private static Predicate<ObjectA> isOPEN() {
    return x -> x.getStatus().equals(Stato.OPEN);
}

private static Predicate<ObjectA> isCLOSED() {
    return x -> x.getStatus().equals(Stato.CLOSED);
}

Now I want just to merge the two object and the third list into one. List should contain programmed item (if present) open object (if present) and after that all closed items. I jave tried with Stream.of, Stream.concat but I always obtain some compilation errors..

Are there some way to do it with Lambdas and with few code?

1
  • List should contain - that doesn't require the usage of streams. list.add(0, open): then list.add(0, programmed): Commented Feb 7, 2022 at 20:31

1 Answer 1

2

If you want to avoid mutation of the closed list, then Stream IPA is one of the possible choices for this task.

It could be done like this:

    public static List<ObjectA> merge(List<ObjectA> closed, ObjectA programmed, ObjectA open) {
        return Stream.concat(Stream.of(programmed, open), 
                             closed.stream())
                .collect(Collectors.toList());
    }

And as I've already mentioned in the comment if are not concerned about preserving the initial state of the closed list, then these objects can be added directly to the list. Since adding a new element at the beginning of the list is costly (if it's backed by the array), a better option will be make use of addAll() and add both values in one operation as Holger suggested :

        closed.addAll(0, Arrays.asList(programmed, open));

Side note:

  • There's an inconsistency in how you are obtaining a programmed object and open object. If a programmed object doesn't exist your decided to return null. But if there's no open object, method get() will raise NoSuchElementException.
ObjectA programmed = all.stream().filter(isPROGRAMMED()).reduce((x,y) -> y).orElse(null);
ObjectA open = all.stream().filter(isOPEN()).findFirst().get();
Sign up to request clarification or add additional context in comments.

4 Comments

Thanks Alexander! Yes I have already tried the solution list.add(0, object) but I wounted to find out if a lambda solution was less verbose!
@CoderJammer well, it's relatively concise. Its main advantage is that doesn't mutate the source of data. You could also replace collect(Collectors.toList()) with toList() if you are using the latest version of Java.
Mind that add(0, …) on an ArrayList has to copy all elements from this index and above to a new position and doing it twice in a row on index zero means copying the entire list twice. So it’s preferable to use closed.addAll(0, Arrays.asList(programmed, open)); as its not only a single statement but also avoiding the unnecessary copying overhead. When you are using Java 9 or newer and know that neither, programmed nor open, is null, you can use the even better closed.addAll(0, List.of(programmed, open));.
@Holger that's a good point with addAll! I'll edit the answer. Method List.of() is null-hostile and it seems like programmed could be null, so in the absence of clarifications from the PO Arrays.asList looks like a better option.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.