Building object from unusually custom object Say we have this method which is my main concern for this question. It's really not optimal way to get values out of it. Each time I'm running through list twice for to just get one field value for NotificationSettingsDto

private NotificationSettingsDto notificationSettingsCustomPairToDto(List&lt;CustomPair&gt; notificationSettingsCustomPair) {
    return NotificationSettingsDto.builder()
            .campaignEvents(notificationSettingsCustomPair.stream()
                    .anyMatch(customPair -&gt; customPair.getKey().equals("campaignEvents")) ?
                    (Boolean) notificationSettingsCustomPair.stream().filter(customPair -&gt; customPair.getKey().equals("campaignEvents")).collect(Collectors.toList()).get(0).getValue() : null)
            .drawResultEvents(notificationSettingsCustomPair.stream()
                    .anyMatch(customPair -&gt; customPair.getKey().equals("drawResultEvents")) ?
                    (Boolean) notificationSettingsCustomPair.stream().filter(customPair -&gt; customPair.getKey().equals("drawResultEvents")).collect(Collectors.toList()).get(0).getValue() : null)
            .transactionEvents(notificationSettingsCustomPair.stream()
                    .anyMatch(customPair -&gt; customPair.getKey().equals("transactionEvents")) ?
                    (Boolean) notificationSettingsCustomPair.stream().filter(customPair -&gt; customPair.getKey().equals("transactionEvents")).collect(Collectors.toList()).get(0).getValue() : null)
            .userWonEvents(notificationSettingsCustomPair.stream()
                    .anyMatch(customPair -&gt; customPair.getKey().equals("userWonEvents")) ?
                    (Boolean) notificationSettingsCustomPair.stream().filter(customPair -&gt; customPair.getKey().equals("userWonEvents")).collect(Collectors.toList()).get(0).getValue() : null)
            .build();
}


And I'm passing following List which consists of CustomPair

List&lt;CustomPair&gt; notificationSettingsCustomPair = Arrays.asList(
        new CustomPair&lt;&gt;("campaignEvents", true),
        new CustomPair&lt;&gt;("drawResultEvents", true),
        new CustomPair&lt;&gt;("transactionEvents", true),
        new CustomPair&lt;&gt;("userWonEvents", true));


List can also have different shapes for example like this :

   List&lt;CustomPair&gt; notificationSettingsCustomPair = Arrays.asList(
        new CustomPair&lt;&gt;("campaignEvents", true),
        new CustomPair&lt;&gt;("transactionEvents", false));


Or like this, you get the idea it can be in any order, with any of these 4 different fields:

     List&lt;CustomPair&gt; notificationSettingsCustomPair = Arrays.asList(
        new CustomPair&lt;&gt;("transactionEvents", true));


Model for CustomPair :

public class CustomPair&lt;K, V&gt; {
private K key;
private V value;
}


Model for NotificationSettingsDto : 

@Builder
public class NotificationSettingsDto {

private Boolean campaignEvents;
private Boolean drawResultEvents;
private Boolean transactionEvents;
private Boolean userWonEvents;
}
notificationSettingsCustomPair.stream()
                    .anyMatch(cp-&gt; cp.getKey().equals(something)) ?
                    (Boolean) notificationSettingsCustomPair.stream().filter(cp  -&gt; cp.getKey().equals(something)).collect(toList()).get(0).getValue() : null


can be replaced by

notificationSettingsCustomPair.stream().filter(cp  -&gt; cp.getKey().equals(something)).findFirst().map(v -&gt; v.getValue()).orElse(null)


It's now only streamed once.

Please note that you use your list like a Set which I find strange, you should consider looking at Set specificities.