Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to map multiple variable in Java lambda? [closed]

I have a method that filters in a List containing enums i

if (availableImageSizes.stream()
                       .filter(t -> t.getNameSuffix().equals("-xs"))
                       .findFirst().isPresent())
{
    int width = availableImageSizes.stream()
                       .filter(t -> t.getNameSuffix().equals("-xs"))
                       .findFirst().getWidth();

    int height = availableImageSizes.stream()
                       .filter(t -> t.getNameSuffix().equals("-xs"))
                       .findFirst().getHeight();
}

As you see I try to filter the list according to its NameSuffix and after filtering I want to map that value's width and height to a variable. But the code is wrong and even if it works, it is so ugly.

Can I map multiple variable in one lambda? If so, how can I achieve this?

like image 343
Chris Garsonn Avatar asked Apr 28 '26 14:04

Chris Garsonn


2 Answers

If you need the values as part of the method's return value

If there is a sensible default, I'd do it like this

Optional<ImageSize> xsImageSize = availableImageSizes.stream()
    .filter(t -> t.getNameSuffix().equals("-xs"))
    .findFirst();
int height = xsImageSize.map(ImageSize::getHeight).orElse(-1);
int width = xsImageSize.map(ImageSize::getWidth).orElse(-1);

Alternatively, nullable Integers

Integer height = xsImageSize.map(ImageSize::getHeight).orElse(null);
Integer width = xsImageSize.map(ImageSize::getWidth).orElse(null);

Otherwise

Optional<ImageSize> xsImageSize = availableImageSizes.stream()
    .filter(t -> t.getNameSuffix().equals("-xs"))
    .findFirst();
if (xsImageSize.isPresent())
{
    int height = xsImageSize.get().getHeight();
    int width = xsImageSize.get().getWidth();
    //...
}

If you don't need those values for the return

availableImageSizes.stream()
    .filter(t -> t.getNameSuffix().equals("-xs"))
    .findFirst()
    .ifPresent(imageSize -> {
        int height = imageSize.getHeight();
        int width = imageSize.getWidth();
        //...
    });

or

availableImageSizes.stream()
    .filter(t -> t.getNameSuffix().equals("-xs"))
    .findFirst()
    .ifPresent(this::processXsImageSize);

//...
private void processXsImageSize(ImageSize imageSize) {
    int height = imageSize.getHeight();
    int width = imageSize.getWidth();
    //...
}
like image 96
Michael Avatar answered May 01 '26 04:05

Michael


First of all, your goal is to remove duplicated code:

availableImageSizes.stream()
                   .filter(t -> t.getNameSuffix().equals("-xs"))
                   .findFirst()

I am not sure what "in one lamba" means. However, you can achieve this with a single chain of Stream and Optional method calls. However, you are not able to retrun two or more values at once. The solution is to return either an array to be decomposed to width and height. In better case use a custom object Dimension/Point class or Pair/AbstractMap.SimpleEntry.

The arrays is the easiest way to show the solution.

Integer[] dimensions = availableImageSizes.stream()
    .filter(t -> t.getNameSuffix().equals("-xs"))                // images with a suffix
    .findFirst()                                                 // Optional<MyImage>
    .map(obj -> new Integer[] {obj.getWidth(), obj.getHeight()}) // map dimensions
    .orElse(new Integer[] {null, null});                         // else default values
        
Integer width = dimensions[0];                                   // destructured width
Integer height = dimensions[1];                                  // destructured height
like image 35
Nikolas Charalambidis Avatar answered May 01 '26 02:05

Nikolas Charalambidis



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!