Converting the some logic using java Stream - java

I would Like to convert some logic using Java8 Stream. How should we modify the code?
public boolean isBFOrder(final BFReturn pReturnRequest) {
ArrayList<BFReturnShip> shipGroupList =pReturnRequest.getShipGroupList();
Boolean bfOrder = false;
for(BFReturnShip bfReturnShip : shipGroupList) {
if(bfReturnShip.getModeOfReturn().equals(TYPE)) {
bfOrder = true;
} else {
return false;
}
}
return bfOrder;
}

return pReturnRequest.getShipGroupList()
.stream()
.allMatch(i -> i.getModeOfReturn().equals(REFUND_ONLY));
Provided that pReturnRequest.getShipGroupList() is never null.
As #Holger points out, we can improve the piece above by covering the case where the list comes empty.
final List<BFReturnShip> list = pReturnRequest.getShipGroupList();
return !list.isEmpty() &&
list.stream().allMatch(i -> i.getModeOfReturn().equals(REFUND_ONLY));

Related

How to transform this piece of code using Java 8?

I am trying to transform this piece of code using Java 8.
private boolean hasOneFuelType(final List<PoiBE> pois) {
for(PoiBE poiBE: pois) {
if(poiBE.getDetails().getSimpleRefueling().getTypes().size() > 1) {
return false;
}
}
return true;
}
So, in the code above I want to return false if in the list of pois has at least one poi that has a list of Types that is bigger then 1, otherwise I want to return true.
I tried this code, but apparently is not correct.
pois.stream().anyMatch(poiBE -> {
if(poiBE.getDetails().getSimpleRefueling().getTypes().size() > 1) {
return false;
}
return true;
});
return true;
noneMatch returns false if any item in the stream matches the given predicate, and true otherwise.
return pois.stream()
.noneMatch(poiBE -> poiBE.getDetails().getSimpleRefueling().getTypes().size() > 1);
You're close.
The return statements inside the anyMatch don't return from your method, but from the lambda passed to anyMatch:
boolean anyHasMoreThanOneFuelType = pois.stream().anyMatch(poiBE -> {
if(poiBE.getDetails().getSimpleRefueling().getTypes().size() > 1) {
return true;
}
return false;
});
return !anyHasMoreThanOneFuelType;
This of course can be simplified if you replace anyMatch with noneMatch and skip the unnecessary if by directly returning the boolean result of the comparison:
return pois.stream().noneMatch(
poiBE -> poiBE.getDetails().getSimpleRefueling().getTypes().size() > 1);
You can use
return pois.stream()
.noneMatch(poiBE -> poiBE.getDetails().getSimpleRefueling().getTypes().size() > 1);
return pois.stream().allMatch(
poiBE -> poiBE.getDetails().getSimpleRefueling().getTypes().size() <= 1);

Is there a way to merge this 2?

I'm running out of idea of how will I merge this 2 conditions, it has the same return so I need to merge
if ((StringUtils.isBlank(ext))) {
return true;
}
for (String str : INVALID_EXTENSION_ARR) {
if (ext.matches(str)) {
return true;
} else if (ext.matches(str.toLowerCase())) {
return true;
}
}
You don't need a loop.
Populate INVALID_EXTENSION_ARR with values in lowercase:
private static final List<String> INVALID_EXTENSION_ARR = Arrays.asList("foo", "bar", "whatever"); // Note: All in lowercase!
Then it's just one line:
return StringUtils.isBlank(ext) || INVALID_EXTENSION_ARR.contains(ext.toLowerCase());
Note: I have assumed when you used matches() you meant to use equals().
——-
If the list of acceptable extensions is “large” (say, more than 10), you’ll get better performance if you use a Set instead of a List:
private static final Set<String> INVALID_EXTENSION_ARR = new HashSet<>(Arrays.asList("foo", "bar", "whatever"));
Or for recent java versions:
private static final Set<String> INVALID_EXTENSION_ARR = Set.of("foo", "bar", "whatever");
But you would be unlikely to notice much difference unless the size was more than say 100.
Assuming that the loop will always be entered into,
for (String str : INVALID_EXTENSION_ARR) {
if (StringUtils.isBlank(ext) || ext.matches(str)) {
return true;
} else if (ext.matches(str.toLowerCase())) {
return true;
}
}
but I think that way that had it was easier to read and does not need to re-evaluate StringUtils.isBlank(ext) every time.
It is helpful if you provide more context, but this is one of the ways you can compact it.
for (String str : INVALID_EXTENSION_ARR) {
if (StringUtils.isBlank(ext) || ext.toLowerCase().matches(str.toLowerCase())) {
return true;
}
}

Comparing list of objects in Java 8

This post may be duplicate one, apologies for that.
I have worked extensively in Java-6, now moving to Java 8. Is there an efficient way to rewrite the below logic in Java 8?
This compares list of objects with single object, returning true if some object in the list has a matching "Identifier" parameter value.
private boolean compareOrder(UserOrderDTO.OrderConfig givenDeviceConfig, List<UserOrderDTO.OrderConfig> masterConfigList) {
boolean isValidService = false;
for(UserOrderDTO.OrderConfig eachRecord:masterConfigList) {
if(eachRecord.getIdentifier()!=null && givenDeviceConfig.getIdentifier()!=null) {
if(eachRecord.getIdentifier().trim().equalsIgnoreCase(givenDeviceConfig.getIdentifier().trim()) ) {
isValidService = true;
break;
}
}
}
return isValidService;
}
Also if I want to compare two list, any suggestions please
List<UserOrderDTO.OrderConfig> oneList = some value;
List<UserOrderDTO.OrderConfig> twoList = some value;
private boolean compareOrder(UserOrderDTO.OrderConfig givenDeviceConfig, List<UserOrderDTO.OrderConfig> masterConfigList) {
return givenDeviceConfig.getIdentifier() != null
&& masterConfigList.stream().anyMatch(
p -> p.getIdentifier() != null
&& p.getIdentifier().trim().equalsIgnoreCase(givenDeviceConfig.getIdentifier().trim()));
}
.
private static boolean compareOrderLists(List<UserOrderDTO.OrderConfig> list1, List<UserOrderDTO.OrderConfig> list2) {
return list1.stream().anyMatch(
p -> p.getIdentifier() != null
&& list2.stream().anyMatch(
p2 -> p2.getIdentifier() != null
&& p2.getIdentifier().trim().equalsIgnoreCase(p.getIdentifier())));
}
private boolean compareOrder(OrderConfig givenDeviceConfig, List<OrderConfig> masterConfigList) {
//do null and empty checks here
return masterConfigList
.stream()
.anyMatch(o -> o.getIdentifier().equalsIgnoreCase(givenDeviceConfig.getIdentifier()));
}
You can use this for list comparison. If you don't want to include a library, there are plenty of answers on stackoverflow to compare Collections.

Java - how to return to a parent method?

I'm working on a method which should check in a guest to a room if the password matches. The method should also return that room.
public Room checkIn(String password, String guestName) {
assert (guestName != null);
if (this.password.testWord(password) && roomList.stream().allMatch(r -> r.getGuest().getName() != guestName)) {
roomList.forEach(r -> {
if (r.getGuest() == null) {
new Guest(guestName).checkin(r);
return r;
}
});
}
return null;
}
Eclipse gives me an error about returning within the forEach() method, since forEach() shouldn't return anything. I'm trying to have the checkIn() method return the room. Is there any way I can do this?
Use Stream.findFirst() to get the first matching element:
Optional<Room> r = roomList.stream().filter(r -> r.getGuest() == null).findFirst();
if (r.isPresent()) {
new Guest(guestName).checkin(r.get());
return r.get();
}

Iterating on list with stream in java 8

what would be most optimal way to rewrite this iteration with java 8 stream().
for (name : names){
if(name == a){
doSomething();
break;
}
if(name == b){
doSomethingElse();
break;
}
if(name == c){
doSomethingElseElse();
break;
}
}
Basically, iterating over the list with 3 conditions if any of them is satisfied want to break loop and in every condition want to call different method.
You can use anyMatch to find the first element matching one of your conditions and terminate. Use side effects for calling the processing methods :
boolean found =
names.stream()
.anyMatch (name -> {
if (name.equals(a)) {
doSomething();
return true;
} else if (name.equals(b)) {
doSomethingElse ();
return true;
} else if (name.equals(c)) {
doSomethingElseElse ();
return true;
} else {
return false;
}
}
);
Pretty ugly, but does what you asked in a single iteration.
The answer by Eran is definitely the straightforward way of performing the search. However, I would like to propose a slightly different approach:
private static final Map<String, Runnable> stringToRunnable = new HashMap<>();
{
stringToRunnable.put("a", this::doSomething);
stringToRunnable.put("b", this::doSomethingElse);
stringToRunnable.put("c", this::doSomethingElseElse);
}
public static void main(String[] args) {
List<String> names = Arrays.asList("1", "2", "b", "a");
names.stream()
.filter(stringToRunnable::containsKey)
.findFirst()
.ifPresent(name -> stringToRunnable.get(name).run());
}
private void doSomethingElseElse() {
}
private void doSomethingElse() {
}
public void doSomething() {
}
The part that does the job is the code below, but I added it to a main() function assuming a, b, and c are strings. However, the idea would work with any datatype.
names.stream()
.filter(stringToRunnable::containsKey)
.findFirst()
.ifPresent(name -> stringToRunnable.get(name).run());
The idea is to keep a map of keys and Runnables. By having Runnable as value it is possible to define a void method reference without parameters. The stream first filters away all values not present in the map, then finds the first hit, and executes its method if found.
Collection collection;
collection.forEach(name->{
if(name.equals(a))){
doSomething();
}
if(name.equals(b)){
doSomethingElse();
}
if(name.equals(c)){
doSomethingElseElse();
}
});

Categories