Java8 Way to Handle If..Else Check in Collections

Java8 way to handle if..else check in Collections

I'd go for getOrDefault on the map, like this:

if(allLists.getOrDefault("fruits", Collections.emptyList()).contains("Apple"))
System.out.println("Having apples");

Basically, this eliminates the key-not-present check you normally do. In situations, where you want to continue to work with the list (grouping in maps), you may also check out computeIfAbsent.

Handling nested if/else statements using Java 8 streams

If at least one of the values is guaranteed, you could refactor it like this:

public List<UserAction> getUserActionList(Map<String, String> map) {
return Stream.of("userid", "username", "userrole")
.map(map::get)
.filter(s -> !checkForNullEmpty(s))
.limit(1)
.map(output -> new UserAction(map, output))
.collect(Collectors.toList());
}

If it is not guaranteed that at least one value will be non-null, it's a little uglier, but not too bad:

public List<UserAction> getUserActionList(Map<String, String> map) {
return Stream.of("userid", "username", "userrole")
.map(map::get)
.filter(s -> !checkForNullEmpty(s))
.limit(1)
.map(output -> new UserAction(map, output))
.map(Collections::singletonList)
.findFirst()
.orElseGet(() -> Arrays.asList(new UserAction(map, null)));
}

how to check if all elements of java collection match some condition?

If you have java 8, use stream's allMatch function (reference):

 ArrayList<Integer> col = ...;
col.stream().allMatch(i -> i>0); //for example all integers bigger than zero

Java 8: Lambda-Streams, Filter by Method with Exception

You must catch the exception before it escapes the lambda:

s = s.filter(a -> {
try {
return a.isActive();
} catch (IOException e) {
throw new UncheckedIOException(e);
}
});

Consider the fact that the lambda isn't evaluated at the place you write it, but at some completely unrelated place, within a JDK class. So that would be the point where that checked exception would be thrown, and at that place it isn't declared.

You can deal with it by using a wrapper of your lambda that translates checked exceptions to unchecked ones:

public static <T> T uncheckCall(Callable<T> callable) {
try {
return callable.call();
} catch (RuntimeException e) {
throw e;
} catch (Exception e) {
throw new RuntimeException(e);
}
}

Your example would be written as

return s.filter(a -> uncheckCall(a::isActive))
.map(Account::getNumber)
.collect(toSet());

In my projects I deal with this issue without wrapping; instead I use a method which effectively defuses compiler's checking of exceptions. Needless to say, this should be handled with care and everybody on the project must be aware that a checked exception may appear where it is not declared. This is the plumbing code:

public static <T> T uncheckCall(Callable<T> callable) {
try {
return callable.call();
} catch (Exception e) {
return sneakyThrow(e);
}
}

public static void uncheckRun(RunnableExc r) {
try {
r.run();
} catch (Exception e) {
sneakyThrow(e);
}
}

public interface RunnableExc {
void run() throws Exception;
}

@SuppressWarnings("unchecked")
private static <T extends Throwable> void sneakyThrow(Throwable t) throws T {
throw (T) t;
}

and you can expect to get an IOException thrown in your face, even though collect does not declare it. In most, but not all real-life cases you would want to just rethrow the exception, anyway, and handle it as a generic failure. In all those cases, nothing is lost in clarity or correctness. Just beware of those other cases, where you would actually want to react to the exception on the spot. The developer will not be made aware by the compiler that there is an IOException to catch there and the compiler will in fact complain if you try to catch it because we have fooled it into believing that no such exception can be thrown.

Handling null checks in java 8 Collection Sort method within a Lambda using Comparable

Using Comparator.nullsFirst or Comparator.nullsLast would be the correct choice.

If you need null values at first. You could use this

Collections.sort(members, (m1, m2) -> {
if(m1.getPerson() == null || m2.getPerson() == null ||
m1.getPerson().getFirstName() == null || m2.getPerson().getFirstName() == null){
return -1;
}

if(m1.getPerson() != null && m2.getPerson() != null &&
m1.getPerson().getFirstName() != null && m2.getPerson().getFirstName() != null){
return m1.getPerson().getFirstName().compareTo(m2.getPerson().getFirstName());
}
return 0;
});

If you need null values at last. You could use this

Collections.sort(members, (m1, m2) -> {
if(m1.getPerson() == null && m2.getPerson() == null &&
m1.getPerson().getFirstName() == null && m2.getPerson().getFirstName() == null){
return -1;
}

if(m1.getPerson() != null && m2.getPerson() != null &&
m1.getPerson().getFirstName() != null && m2.getPerson().getFirstName() != null){
return m1.getPerson().getFirstName().compareTo(m2.getPerson().getFirstName());
}
return 0;
});

Optimized approach would be.

Collections.sort(members, (m1, m2) -> {
if (m1.getPerson() == null || m2.getPerson() == null ||
m1.getPerson().getFirstName() == null ||
m2.getPerson().getFirstName() == null) {
return -1;
} else {
return m1.getPerson().getFirstName().compareTo(m2.getPerson().getFirstName());
}
});


Related Topics



Leave a reply



Submit