41

In short, I have this code, and I'd like to get an specific element of the array using a condition and lambda. The code would be something like this:

Preset[] presets = presetDALC.getList();
Preset preset = Arrays.stream(presets).select(x -> x.getName().equals("MyString"));

But obviously this does not work. In C# would be something similar but in Java, how do I do this?

4 Answers 4

72

You can do it like this,

Optional<Preset> optional = Arrays.stream(presets)
                                  .filter(x -> "MyString".equals(x.getName()))
                                  .findFirst();

// Check whether optional has element you are looking for
if (optional.isPresent()) {
    Preset p = optional.get(); // Get it from optional
}

You can read more about Optional here.

Sign up to request clarification or add additional context in comments.

3 Comments

Using isPresent() and .get() is discouraged as it kills the purpose of using optional.
Not directly. The main reason to use Optional is to force a check (to trigger a bug as early as possibly). Using get() is okay if you can prove that it holds, which he does. I agree though that in general its better to use the alternatives. But there are many situations in which you can not directly name a default or want to throw an exception, instead you may want to have the error handling in the if-else of isPresent() and then use get().
Your answer was helpful for me. I wanted the same exact thing. Thanks.
35

Like this:

Optional<Preset> preset = Arrays
        .stream(presets)
        .filter(x -> x.getName().equals("MyString"))
        .findFirst();

This will return an Optional which might or might not contain a value. If you want to get rid of the Optional altogether:

Preset preset = Arrays
        .stream(presets)
        .filter(x -> x.getName().equals("MyString"))
        .findFirst()
        .orElse(null);

The filter() operation is an intermediate operation which returns a lazy stream, so there's no need to worry about the entire array being filtered even after a match is encountered.

Comments

12

Do you want first matching, or all matching?

String[] presets = {"A", "B", "C", "D", "CA"};

// Find all matching
List<String> resultList = Arrays.stream(presets)
                                .filter(x -> x.startsWith("C"))
                                .collect(Collectors.toList());
System.out.println(resultList);

// Find first matching
String firstResult = Arrays.stream(presets)
                           .filter(x -> x.startsWith("C"))
                           .findFirst()
                           .orElse(null);
System.out.println(firstResult);

Output

[C, CA]
C

Comments

0

One-liner since Java 8:

Preset found = Stream.of(presets)
    .filter(p -> p.getName().equals("MyString"))
    .findFirst().orElseThrow();

Avoid declaring Optional<>, that returned from findFirst as a variable or a parameter. It is designed for return types / "one-liner" styles.

3 Comments

Is there a one-liner that doesn't throw an exception in the case of a missing element? E.g. something you could toss into a conditional so you can then add the missing element if needed.
@Fopedush, absolutely: ...findFirst().orElse(MY_EMPTY_OBJ);. See: docs.oracle.com/javase/9/docs/api/java/util/…
Am I being overly pedantic when I point out that this "one-liner" wraps to three lines, and that's only because you didn't include newlines for 4 of the method calls? :D

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.