How to transform this piece of code using Java 8? - java

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);

Related

Converting the some logic using java Stream

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));

Why this if statement is not redudant in NetBeans 8.2

I wrote a method in java class like this:
public boolean checkPlace() {
if (this.PlaceName.equals("Name Place"))
return true;
else return false;
}
I wonder why it is not redudant.
Could I write just return if statement?
Thanks in advance.
You could write:
public boolean checkPlace() {
return PlaceName.equals("Name Place");
}
It is redundant in general. Best practice would be to write
if (this.PlaceName.equals("Name Place")) {
return true;
}
return false;
Or if that is not just a dummy example
return this.PlaceName.equals("Name Place")
If you are more used to expression-like syntax from other languages, then Java does not allow you to write
return if (this.PlaceName.equals("Name Place")) true else false;
However it does support ternary expressions in which case you have to be sure you only have 2 branches and not more.
return this.PlaceName.equals("Name Place") ? true : false;

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();
}

how to use return keyword in a find operation in binary search tree

This is my method to find if a particular node is there in a binary tree.Here's my method and it works fine.
public boolean find(BinaryNode p,int x){
if(p==null){
return false ;
}
else{
if(x==p.element){
return true;
}
else if(x<p.element){
return find(p.left,x);
}
else {
return find(p.right,x);
}
}
}
My question is if I don't insert return keyword inside else if(x<p.element){ and else { I get an error as missing return statement.
Say I have a binary tree consisting of elements 5,4,6,60,25,10 .
So if i am searching for 10 there's a time that
if(x==p.element){
return true;
is satisfied because of recursive calls.Then there's a return statement to be found.
If i am searching for an element that's not in tree eventually I would reach the statement
if(p==null){
return false ;
},there we find a return statement.
Therefore even I don't have the return in else if and else clauses somehow there's a way that I finally reach a return statement right?So what's wrong with not having return keyword in else if and else clauses.
Why do I have to have it there?
Why can't I do it as
`public boolean find(BinaryNode p,int x){
if(p==null){
return false ;
}
else{
if(x==p.element){
return true;
}
else if(x<p.element){
find(p.left,x);
}
else {
find(p.right,x);
}
}
}`
The closest to the way you want your if-else if-else clause to behave is using the ? conditional expression:
public boolean find(BinaryNode p,int x)
{
if(p==null) {
return false ;
}
else {
return (x==p.element)?true:(x<p.element?find(p.left,x):find(p.right,x));
}
}
Other option is to store the value to be returned in a local variable and only return it at the end of your method:
public boolean find(BinaryNode p,int x)
{
boolean returnValue = false;
if(p!=null)
{
if(x==p.element){
returnValue = true;
}
else if(x<p.element){
returnValue = find(p.left,x);
}
else {
returnValue = find(p.right,x);
}
}
return returnValue;
}
And my favorite way, using short-circuit evaluation of logical expressions:
public boolean find(BinaryNode p,int x)
{
if(p==null) return false;
return x==p.element || (x<p.element && find(p.left,x)) || find(p.right,x);
}
Since Java's || and && operators won't evaluate their right part expression when the left part already determines their result. If x==p.element is true, then true will be returned without evaluation the rest of the line. If not, then (x<p.element && find(p.left,x)) will be evaluated following the same rule.
Note how find(p.left,x) won't be evaluated when x<p.element is false.
You need return statement because the find-function in the else if - else statement will return to the caller after its done, but the first-call function still have to return a value to the caller
Therefore even I don't have the return in else if and else clauses somehow there's a way that I finally reach a return statement right?
No compiler doesn't know about it. Compiler doesn't know what will be value of x and p at run-time.
Compiler simply checks for all the possibilities of the return statement and there must be exit point of the method.
You need to provide the logic to move either in right direction or left direction of the binary tree.
The last two else-if are not responsible to actually return the result of the find method its used just to move in the right direction of the tree. Ultimately final result of the the find method will come out by first two if-else clause.

Greater-than compare-and-swap

As the title suggests, I'm looking for a compare-and-swap implementation, but with greater-than comparison:
if(newValue > oldValue) {
oldValue = newValue;
}
where oldValue is some global shared state and newValue is private to each thread, without doing this:
synchronized(locker) {
if(newValue > oldValue) {
oldValue = newValue;
}
}
because I want a non-blocking solution. From studying source codes of other non-blocking operations, I've come up with this (assuming the values are integers):
AtomicInteger oldValue; // shared global variable
...
public boolean GreaterThanCAS(int newValue) {
while(true) {
int local = oldValue;
if(local == oldValue) {
if(newValue > local) {
if(oldValue.compareAndSet(local, newValue) {
return true; // swap successful
} // else keep looping
} else {
return false; // swap failed
}
} // else keep looping
}
}
when // else keep looping happens, it means that another thread has changed the oldValue in the meantime and so I need to loop and try again.
Is this implementation correct (thread-safe)?
Since Java 8 this can be simplified with use of updateAndGet:
public boolean greaterThanCAS(int newValue) {
return oldValue.updateAndGet(x -> x < newValue ? newValue : x) == newValue;
}
Note that this would return true also in case when old and new values are equal.
Give a try to #Adam's answer if this is not desired behaviour.
I see no problems with your implementation, provided that no thread ever decreases the value of the AtomicInteger. If they do, your code is open to race conditions.
Note that the code can be simplified as follows:
public boolean GreaterThanCAS(int newValue) {
while(true) {
int local = oldValue.get();
if(newValue <= local) {
return false; // swap failed
}
if(oldValue.compareAndSet(local, newValue)) {
return true; // swap successful
}
// keep trying
}
}
I would re write it to look more like:
while(true) {
int local = oldValue.get();
if(newValue > local){
if(oldValue.compareAndSwap(local, newValue) {
return true; // swap successful
} // else keep looping
}else
return false;
}
The equivalence check before the greater than check is redundant.
Otherwise it should work fine.
#Vadzim, I would have commented on your post, but stackoverflow says I don't have enough points to post comments. Your answer is almost correct, but your function will always return false because getAndUpdate always returns the previous value, or 'x' in your case. I think all you would need to do is replace your last '==' with '<', e.g.:
// return true if the assignment was made, false otherwise
public boolean greaterThanCAS(int newValue) {
return oldValue.getAndUpdate(x -> x < newValue ? newValue : x) < newValue;
}

Categories