For Loop to Java 8 Stream forEach() [duplicate] - java

This question already has answers here:
Break or return from Java 8 stream forEach?
(14 answers)
Closed 4 years ago.
I have a for loop for a list that checks whether or not index values exist in the db.
Simply if any value doesn't exist, it immediately returns false.
public boolean exists(List<String> keys) {
for(String key: keys) {
boolean exists = service.existsByKey(key);
if(!exists) return false;
}
return true;
}
I tried to change it to java 8 foreach, but it doesn't work as expected.
keys.stream().forEach(k -> {
boolean exists = service.existsByKey(k);
if(!exists) return false;
});
Am I missing something? Why doesn't it go in if(!exists) staetment in forEach()?

Your return statements in forEach method are ignored.
Try to use
boolean exists = key.stream().allMatch(k -> service.existsByKey(k));

You cannot return a value with the forEach construct as it accepts a consumer i.e. a function that takes one parameter and returns nothing(void), instead, you can use allMatch as shown in the other answer ornoneMatch like this:
return keys.stream()
.noneMatch(key -> !service.existsByKey(key))

You use lambda that is mostly a shortcut for anonymous class.
So your code is equivalent to:
keys.stream().forEach(new Consumer<String>() {
#Override
public void accept(String s) {
boolean exists = service.existsByKey(k);
if(!exists) return false;
}
});
It doesn't return from your method (actually it doesn't compile also).

Related

Java 11 Lambda - check each object, return true when the first condition is met, else return false [duplicate]

This question already has answers here:
Java how to use stream map to return boolean [duplicate]
(2 answers)
How to match stream elements but return false if non exists?
(6 answers)
Use Streams to return Boolean if all the List values in a Map are empty/not-empty
(3 answers)
How to use stream on method that return boolean value with condition
(4 answers)
Closed 2 years ago.
I have a method that works fine. This is how it looks.
private boolean roomWithMoreThanTenFurnitures(Building building) {
if (building != null && building.hasRooms()) {
for (Room room : building.getRooms()) {
if (room.getFurnitures.size() > 10) {
return true;
}
}
}
return false;
}
I wanna switch this to Lambda. In came uo with the shell, but I am not sure how fill in the if (condition) return true or return false outside.
building.getRooms().forEach(room -> {
//??
});
You cannot do it this way - the foreach is for executing some action for every of the collection/stream element not for filtering them or mapping to a result
You need e.g. anyMatch method - for example
building.getRooms().stream().anyMatch(room -> room.getFurnitures.size() > 10)
You can do it like this. Returns false based on the initial conditions, then streams the rooms. This presumes the rooms can be streamed (e.g a List). If they are an array you will need to do something similar to Arrays.stream(building.getRooms())
private boolean roomWithMoreThanTenFurnitures(Building building) {
if (building != null && building.hasRooms()) {
return building.getRooms().stream()
.anyMatch(room -> room.getFurnitures.size() > 10);
}
return false;
}

How to find a Specific word in a String in Java [duplicate]

This question already has answers here:
How to find a whole word in a String in Java?
(14 answers)
Closed 2 years ago.
I´m doing a project for school and I need my method to return true only to a certain word.
This is what I have:
public boolean scanDescription (String keyword) {
if (description.contains(keyword)) {
return true;
} else {
return false;
}
So for example, if the keyword is "disk", I need this method to return true only when a string contains the word "disk", but my problem is that it returns true when a string contains words like "diskette"
PS.: I have also tried to use .indexOf and it did not work
You should use the word boundary.
public boolean scanDescription(String keyword) {
Pattern pattern = Pattern.compile("\\b"+keyword+"\\b");
return pattern.matcher(description).find();
}

Java - How to assign variables within evaluations? [duplicate]

This question already has answers here:
Is there a post-assignment operator for a boolean?
(3 answers)
Closed 5 years ago.
I'm trying to make a Java method close() which closes object if it is open, and which returns true if the action succeeded.
public boolean close() {
if (open) {
open = false;
return true;
} else {
return false;
}
}
I'm trying to find a way to write this down with less code. What I came up with is the following.
public boolean close() {
return (open && (open = false));
}
Eclipse doesn't give any errors when I write this down. The left hand side of the evaluation checks if open is true, and if so, the right hand side should set open to false and return true as well.
I've tested the code, and open does get set to false, but it doesn't return true. Is there a way to make this work?
Perhaps something like:
public boolean close () {
return open != (open = false);
}
but if I was reviewing this code I would reject it as unclear.
I would probably do it using maximal clarity as:
public boolean close () {
boolean wasOpen = open;
open = false;
return wasOpen;
}
and let the compiler optimise.
You could do it without conditional execution by preparing the return value before the assignment of false, like this:
boolean wasOpen = open;
open = false;
return wasOpen;
return open ? !(open = false) : open;
or
return open ? !(open = false) : false;
Though, I don't like the idea of making the first snippet shorter. You are killing readability where it's already absent.
Personally, I would go with the original method introducing a local variable wasOpen as #dasblinkenlight suggested.
Not really, the assignment is evaluated prior to the rest of the expression, so what you're essentially saying is:
true && false
Also known as false
Your expression will evaluated as the following true && false,so the result is false
public boolean close() {
if(!open) return open;
open=false;
return true;
}
You can try this
public boolean close()
{ return !open = (open == true) ? false: true; }

how to break a function in java [duplicate]

This question already has answers here:
How do I break out of nested loops in Java?
(37 answers)
What does it mean to return a value?
(3 answers)
Closed 5 years ago.
guys i am a beginner in java ... i want to make a function to loop through a hashmap for example it contains
0[3],3[4,5],6[2]
and to break when the method isSiteInherited is true else return false... here is what i made
private boolean isInherited() {
boolean isInherited = false;
for (Entry<Integer, Set<Integer>> entry : siteIndeciesMap.entrySet()) {
for (Integer index : entry.getValue()) {
if(isSiteInherited(index)){
break;
}
}
}
return false;
}
if not sites are found inherited return false and if it enters the break it should break from all the method ... so what is wrong with this method
Seems to be like you want to return instead of break. Without the use of labels, break only gets you out of one layer of loops anyway, and in this case, you need to report overall success, which isn't something your current approach does.
private boolean isInherited() {
for (Entry<Integer, Set<Integer>> entry : siteIndeciesMap.entrySet()) {
for (Integer index : entry.getValue()) {
if (isSiteInherited(index)) {
return true;
}
}
}
return false;
}
You can either use a label to break from the outer loop (https://stackoverflow.com/a/886979/4949918).
The better way would probably be to use a boolean to say that you've broken from the inner loop in the outer loop.
private boolean isInherited() {
boolean isInherited = false;
boolean shouldBreak = false;
for (Entry<Integer, Set<Integer>> entry : siteIndeciesMap.entrySet()) {
for (Integer index : entry.getValue()) {
if(isSiteInherited(index)){
shouldBreak = true;
break;
}
}
if (shouldBreak) {
break;
}
}
return false;
}

How to write it using streams? Java 8

I wrote a piece of code and wonder how I can write it more elegant, using streams
here it is:
public boolean possibleToAddTask(LocalDate taskDate, final String username) {
List<Task> userTasklist = find(username).getTaskList();
for(Task task : userTasklist) {
if(task.getDate().equals(taskDate)){
return false;
}
}
return true;
}
Here - some boolean is returned from a method. If specified date already exists in some task it returns false, otherwise true (so the return type answers the question raised in method's name :))
I was trying with filters on streams, but It worked just for a while, and then unit tests gave me some unexpected results so I deleted it and wrote it like Its upper. Now I want to beautify it
previously it was like this:
public boolean possibleToAddTask(LocalDate taskDate, final String username) {
List<Task> userTasklist = find(username).getTaskList();
try {
userTasklist.stream().filter(n -> n.getDate().equals(taskDate)).findFirst().get();
return true;
} catch (NoSuchElementException e) {
return false;
}
}
thanks in advance :)
Method findFirst() return an Optional. So you can just check if optional is empty.
return !userTasklist.stream()
.filter(n -> n.getDate().equals(taskDate))
.findFirst().isPresent();
Or even easier approach.
return !userTasklist.stream().anyMatch(n -> n.getDate().equals(taskDate));
EDIT: Now unit tests should pass.
How about doing something lik transforming the List into Set and then calling contains():
return userTasklist.stream().map(Task::getDate).collect(Collectors.toSet()).contains(taskDate);

Categories