Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to combine the filters in streams to simplify

I have this following method that takes in a List of a CustomClass and performs filters using streams and returns at each step based on the result of the filter.

I was wondering if there was a way to simplify the code but combining the filters and statements together to make it more concise and efficient.

public String transform(List<CustomObject> listOfObjects) {

       listOfObjects = listOfObjects.stream()
            .filter(object -> object.objectType().equals("BUSINESS")).toList();

       // Primary check as all object should be of business type 
       // and if nothing exist we throw an exception
       if (listOfObjects.isEmpty()) {
           throw new RuntimeException("NO BUSINESS OBJECT FOUND");

       }

       // All objects are now of business type but we want them to be active
       List<CustomObject> listOfActiveObjects = listOfObjects.stream()
                     .filter(object -> object.objectStatus().equals("ACTIVE"))
                     .toList();

       // If no active object found just return the first business object sorted url

       if (listOfActiveObjects.isEmpty()) {
           return listOfObjects.stream()
                .sorted(Comparator.comparing(CustomObject::url))
                .toList().get(0).getUrl();
       }

       // Active objects are present so now filtered with proper locale

       List<CustomObject> listOfActiveObjectsWithLocale = listOfActiveObjects.stream()
                    .filter(object -> object.locale().equals("en-US"))
                    .toList();

       // If no locale was found just return the first sorted business active url

       if (listOfActiveObjectsWithLocale.isEmpty()) {
           return listOfActiveObjects.stream()
                 .sorted(Comparator.comparing(CustomObject::url))
                 .toList().get(0).getUrl();
       }

       // All filters applied, so within these objects return the sorted business/active/locale url
       return listOfActiveObjectsWithLocale.stream()
              .sorted(Comparator.comparing(CustomObject::url))
              .toList().get(0).getUrl();
   }
like image 502
Saad Avatar asked Dec 07 '25 08:12

Saad


2 Answers

Check for Business objekts first then sort by your priority

public static String transform(List<CustomObject> listOfObjects) {

    // Check if there are any "BUSINESS" objects in the list
    if (listOfObjects.stream().noneMatch(object -> object.objectType().equals("BUSINESS"))) {
        throw new RuntimeException("NO BUSINESS OBJECT FOUND");
    }

    // Sort the objects based on the desired criteria and return the first one
    return listOfObjects.stream()
        .sorted(Comparator
            .comparing((CustomObject object) -> !object.objectType().equals("BUSINESS")) // BUSINESS first
            .thenComparing(object -> !object.objectStatus().equals("ACTIVE")) // then ACTIVE
            .thenComparing(object -> !object.locale().equals("en-US")) // then locale en-US
            .thenComparing(CustomObject::getUrl) // finally by URL
        )
        .findFirst()
        .get()  // Since an element is guaranteed, we can safely call get()
        .getUrl();
}

Edit

The now deleted comment was refering to calling Optional.get() Since in the if condition we made sure that there is at least one Business object, I don't think it is bad. But if you prefer you can change it to something like

public String transform(List<CustomObject> listOfObjects) {

if (listOfObjects.stream().noneMatch(object -> object.objectType().equals("BUSINESS"))) {
    throw new RuntimeException("NO BUSINESS OBJECT FOUND");
}

return listOfObjects.stream()
    .sorted(Comparator
        .comparing((CustomObject object) -> !object.objectType().equals("BUSINESS"))
        .thenComparing(object -> !object.objectStatus().equals("ACTIVE"))
        .thenComparing(object -> !object.locale().equals("en-US"))
        .thenComparing(CustomObject::url)
    )
    .findFirst()
    .map(CustomObject::getUrl)
    .orElseThrow(() -> new RuntimeException("Unexpected error during transformation"));
}
like image 178
Asmir Avatar answered Dec 09 '25 20:12

Asmir


You can try this.

     listOfObjects.stream()
            .filter(object -> object.objectType().equals("BUSINESS"))
            .min(
                Comparator.<CustomObject, Boolean>comparing(object -> object.getObjectStatus().equals("ACTIVE"))
                    .thenComparing(object -> object.getLocale().equals("en-US"))
                    .thenComparing(CustomObject::getUrl)
            )
            .map(CustomObject::getUrl)
            .orElseThrow(() -> new RuntimeException("NO BUSINESS OBJECT FOUND"));
like image 39
talex Avatar answered Dec 09 '25 21:12

talex



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!