Converting to lambda expression with ForEach for a breaking for loop - for-loop

Have the following codes with breaking behavior in a for loop:
package test;
import java.util.Arrays;
import java.util.List;
public class Test {
private static List<Integer> integerList = Arrays.asList(1, 2, 3, 4);
public static void main(String[] args) {
countTo2(integerList);
}
public static void countTo2(List<Integer> integerList) {
for (Integer integer : integerList) {
System.out.println("counting " + integer);
if (integer >= 2) {
System.out.println("returning!");
return;
}
}
}
}
trying to express it with Lambda using forEach() will change the behavior as the for loop is not breaking anymore:
public static void countTo2(List<Integer> integerList) {
integerList.forEach(integer -> {
System.out.println("counting " + integer);
if (integer >= 2) {
System.out.println("returning!");
return;
}
});
}
This actually makes sense as the return; statements are only enforced within the lambda expression itself (within the internal iteration) and not for the whole execution sequence, so is there a way to get the desired behavior (breaking the for loop) using the lambda expression?

The following code is logically equivalent to yours:
public static void countTo2(List<Integer> integerList) {
integerList.stream()
.peek(i -> System.out.println("counting " + i))
.filter(i -> i >= 2)
.findFirst()
.ifPresent(i -> System.out.println("returning!"));
}
If you're confused about anything, please let me know!

What you are looking for is a short-circuit terminal operation and while this is the way to do it:
integerList.stream()
.peek(x -> System.out.println("counting = " + x))
.filter(x -> x >= 2)
.findFirst()
.ifPresent(x -> System.out.println("retunrning"));
That's an equivalent only when dealing with sequential stream. As soon as you add parallel that peek might show elements that you would not expect, because there is no defined processing order, but there is encounter order - meaning that elements will be correctly fed to the terminal operation.

One way I could think of doing that would be using anyMatch and the inverse:
if (integerList.stream().noneMatch(val -> val >= 2)) {
System.out.println("counting " + val);
}
if (integerList.stream().anyMatch(val -> val >= 2)) {
System.out.println("returning!");
}
but internally that would iterate over the list twice and wouldn't be very optimal I believe.

Related

How to call a function inside stream of hash map object , & accumulate sum based on output of method called inside stream

double finalPrice = 0;
for(Map.Entry<Integer, Integer> eachBasketItemEntry:itemsInBasket.entrySet()){
Integer itemId = eachBasketItemEntry.getKey();
if(itemPricingRuleMap.containsKey(itemId)){
//calculate pricing based on pricing rule for that item code
finalPrice+=calculateItemPrice(itemId,eachBasketItemEntry.getValue(),itemPricingRuleMap);
}
else{
throw new IllegalArgumentException("No pricing rule regsitered for the item with item id"+itemId);
}
}
return finalPrice;
private double calculateItemPrice(Integer itemId, Integer itemsCount,Map<Integer, PricingRule> itemPricingRuleMap) {
PricingRule pricingRule = itemPricingRuleMap.get(itemId);
return pricingRule.calculatePrice(itemsCount);
}
How to convert this into java8 streams?
double a1 = itemsInBasket.entrySet().stream().forEach(eachBasketItemEntry->{
double finalPrice = 0;
Integer itemId = eachBasketItemEntry.getKey();
finalPrice+= calculateItemPrice(itemId,eachBasketItemEntry.getValue(),itemPricingRuleMap);
})
Tried doing this but Im unsure how to proceed from here..
Can any one help.
Im new to java 8 streams
Thank you.
You can refer the below sample code whenever some one wants to iterate over the collection and wants to get the reduced single value output.
import java.util.HashMap;
import java.util.Map;
public class Test {
public static void main(String[] args) throws Exception {
Map<String,Integer> employeeSalaryMap = new HashMap<>();
employeeSalaryMap.put("emp1",10000);
employeeSalaryMap.put("emp2",20000);
employeeSalaryMap.put("emp3",30000);
employeeSalaryMap.put("emp4",40000);
employeeSalaryMap.put("emp5",50000);
int totalSalaryOfAllEmployees1 = employeeSalaryMap.values().stream().mapToInt(Integer::intValue).sum();
int totalSalaryOfAllEmployees2 = employeeSalaryMap.entrySet().stream().map(Map.Entry::getValue)
.reduce(Integer::sum).orElseThrow(Exception::new);
System.out.println("totalSalaryOfAllEmployees1:: " + totalSalaryOfAllEmployees1);
System.out.println("totalSalaryOfAllEmployees2:: " + totalSalaryOfAllEmployees2);
}
}
**Output**
totalSalaryOfAllEmployees1:: 150000
totalSalaryOfAllEmployees2:: 150000
Both the operations will give you the same result.
Recommended to use: mapToInt/mapToDouble based on the requirements.
Thanks
You can use .map() to map your result calculated from calculateItemPrice method and then use reduce() operation to get required result.
Wrote a sample example for explanation
import java.util.HashMap;
import java.util.Map;
import java.util.NoSuchElementException;
class Main {
public static void main(String[] args) {
Map<Integer, Integer> itemsInBasket = new HashMap<Integer, Integer>();//Creating HashMap
itemsInBasket.put(1, 5); //Put elements in Map
itemsInBasket.put(2, 6);
itemsInBasket.put(3, 7);
itemsInBasket.put(4, 8);
int a1 = itemsInBasket
.entrySet()
.stream()
.map(e -> (e.getKey() + e.getValue()))
.reduce(Integer::sum).orElseThrow(NoSuchElementException::new);
System.out.println(a1);
}
}
For your case : below code can help
double a1 = itemsInBasket
.entrySet()
.stream()
.map(e->calculateItemPrice(e.getKey(), e.getValue(), itemPricingRuleMap))
.reduce(Double::sum).orElseThrow(NoSuchElementException::new);
EDIT : As #Holger Suggested it can be rewritten as
double a1 = itemsInBasket
.entrySet()
.stream()
.mapToDouble(e->calculateItemPrice(e.getKey(), e.getValue(), itemPricingRuleMap))
.sum().orElseThrow(NoSuchElementException::new);
Let me know in comments further if you face further issues.
Thanks.

Java8 Method chaining for Single object without Stream/Optional?

I felt it easiest to capture my question with the below example. I would like to apply multiple transformations on an object (in this case, they all return same class, Number, but not necessarily). With an Optional (Method 3) or Stream (Method 4), I can use the .map elegantly and legibly. However, when used with a single object, I have to either just make an Optional just to use the .map chaining (with a .get() in the end), or use Stream.of() with a findFirst in the end, which seems like unnecessary work.
[My Preference]: I prefer methods 3 & 4, as they seem better for readability than the pre-java8 options - methods 1 & 2.
[Question]: Is there a better/neater/more preferable/more elegant way of achieving the same than all the methods used here? If not, what method would you use?
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class Tester {
static class Number {
private final int value;
private Number(final int value) {
this.value = value;
}
public int getValue() {
return value;
}
#Override
public String toString() {
return String.valueOf(value);
}
}
private static Number add(final Number number, final int val) {
return new Number(number.getValue() + val);
}
private static Number multiply(final Number number, final int val) {
return new Number(number.getValue() * val);
}
private static Number subtract(final Number number, final int val) {
return new Number(number.getValue() - val);
}
public static void main(final String[] args) {
final Number input = new Number(1);
System.out.println("output1 = " + method1(input)); // 100
System.out.println("output2 = " + method2(input)); // 100
System.out.println("output3 = " + method3(input)); // 100
System.out.println("output4 = " + method4(input)); // 100
processAList();
}
// Processing an object - Method 1
private static Number method1(final Number input) {
return subtract(multiply(add(input, 10), 10), 10);
}
// Processing an object - Method 2
private static Number method2(final Number input) {
final Number added = add(input, 10);
final Number multiplied = multiply(added, 10);
return subtract(multiplied, 10);
}
// Processing an object - Method 3 (Contrived use of Optional)
private static Number method3(final Number input) {
return Optional.of(input)
.map(number -> add(number, 10))
.map(number -> multiply(number, 10))
.map(number -> subtract(number, 10)).get();
}
// Processing an object - Method 4 (Contrived use of Stream)
private static Number method4(final Number input) {
return Stream.of(input)
.map(number -> add(number, 10))
.map(number -> multiply(number, 10))
.map(number -> subtract(number, 10))
.findAny().get();
}
// Processing a list (naturally uses the Stream advantage)
private static void processAList() {
final List<Number> inputs = new ArrayList<>();
inputs.add(new Number(1));
inputs.add(new Number(2));
final List<Number> outputs = inputs.stream()
.map(number -> add(number, 10))
.map(number -> multiply(number, 10))
.map(number -> subtract(number, 10))
.collect(Collectors.toList());
System.out.println("outputs = " + outputs); // [100, 110]
}
}
The solution is to build your methods into your Number class. For example:
static class Number {
// instance variable, constructor and getter unchanged
public Number add(final int val) {
return new Number(getValue() + val);
}
// mulitply() and subtract() in the same way
// toString() unchanged
}
Now your code becomes very simple and readable:
private static Number method5(final Number input) {
return input
.add(10)
.multiply(10)
.subtract(10);
}
You may even write the return statement on one line if you prefer:
return input.add(10).multiply(10).subtract(10);
Edit: If you can't change the Number class, my personal taste would be for method2. Using Optional or Stream would be misuse or at least misplaced and could easily confuse your reader. If you insist, write your own Mandatory class, like Optional except it always holds a value, which makes it simpler. For my part I wouldn't bother.

Java Collector.combiner getting called with supplier values always

Problem : Create a Collector implementation which would multiply stream of Integers in parallel and return Long.
Implementation:
public class ParallelMultiplier implements Collector<Integer, Long, Long> {
#Override
public BiConsumer<Long, Integer> accumulator() {
// TODO Auto-generated method stub
return (operand1, operand2) -> {
System.out.println("Accumulating Values (Accumulator, Element): (" + operand1 + ", " + operand2 + ")");
long Lval = operand1.longValue();
int Ival = operand2.intValue();
Lval *= Ival;
operand1 = Long.valueOf(Lval);
System.out.println("Acc Updated : " + operand1);
};
}
#Override
public Set<java.util.stream.Collector.Characteristics> characteristics() {
// TODO Auto-generated method stub
return Collections.unmodifiableSet(EnumSet.of(UNORDERED));
}
#Override
public BinaryOperator<Long> combiner() {
return (operand1, operand2) -> {
System.out.println("Combining Values : (" + operand1 + ", " + operand2 + ")");
long Lval1 = operand1.longValue();
long Lval2 = operand2.longValue();
Lval1 *= Lval2;
return Long.valueOf(Lval1);
};
}
#Override
public Function<Long, Long> finisher() {
// TODO Auto-generated method stub
return Function.identity();
}
#Override
public Supplier<Long> supplier() {
return () -> new Long(1L);
}
}
Observed Output:
Accumulating Values (Accumulator, Element): (1, 4)
Acc Updated : 4
Accumulating Values (Accumulator, Element): (1, 3)
Acc Updated : 3
Combining Values : (1, 1)
Accumulating Values (Accumulator, Element): (1, 8)
Accumulating Values (Accumulator, Element): (1, 6)
Accumulating Values (Accumulator, Element): (1, 2)
Acc Updated : 2
Acc Updated : 8
Accumulating Values (Accumulator, Element): (1, 5)
Accumulating Values (Accumulator, Element): (1, 1)
Acc Updated : 5
Acc Updated : 6
Combining Values : (1, 1)
Accumulating Values (Accumulator, Element): (1, 7)
Acc Updated : 7
Combining Values : (1, 1)
Combining Values : (1, 1)
Acc Updated : 1
Combining Values : (1, 1)
Combining Values : (1, 1)
Combining Values : (1, 1)
Invocation:
List<Integer> intList = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8);
Collector<Integer, Long, Long> parallelMultiplier = new ParallelMultiplier();
result = intList.parallelStream().collect(parallelMultiplier);
i.e. multiplication result is 1, where it should have been 8 factorial. I am not using 'concurrent' Characteristics either.
Ideally, i should have gotten multiplication result of substreams, fed into combiner() operation, but that seems to be not happening here.
Keeping aside the inefficient implementations of boxing/unboxing, any clue where I might have made mistake??
Your collector is slightly off. Here is a simplified version(the why your does not work - see at the end):
static class ParallelMultiplier implements Collector<Integer, long[], Long> {
#Override
public BiConsumer<long[], Integer> accumulator() {
return (left, right) -> left[0] *= right;
}
#Override
public BinaryOperator<long[]> combiner() {
return (left, right) -> {
left[0] = left[0] * right[0];
return left;
};
}
#Override
public Function<long[], Long> finisher() {
return arr -> arr[0];
}
#Override
public Supplier<long[]> supplier() {
return () -> new long[] { 1L };
}
#Override
public Set<java.util.stream.Collector.Characteristics> characteristics() {
return Collections.unmodifiableSet(EnumSet.noneOf(Characteristics.class));
}
}
You problems can be exemplified like this:
static Long test(Long left, Long right) {
left = left * right;
return left;
}
long l = 12L;
long r = 13L;
test(l, r);
System.out.println(l); // still 12
As Flown stated, Java's primitive wrapper types are immutable and cannot be used as an accumulator. Because you're computing the multiplication in parallel, we'll want to use a thread-safe implementation of a mutable Long, which is an AtomicLong.
import java.util.*;
import java.util.concurrent.atomic.*;
import java.util.function.*;
import java.util.stream.*;
public class ParallelMultiplier implements Collector<Integer, AtomicLong, Long> {
#Override
public BiConsumer<AtomicLong, Integer> accumulator() {
return (operand1, operand2) -> operand1.set(operand1.longValue() * operand2.longValue());
}
#Override
public Set<java.util.stream.Collector.Characteristics> characteristics() {
return Collections.unmodifiableSet(EnumSet.of(Characteristics.UNORDERED));
}
#Override
public BinaryOperator<AtomicLong> combiner() {
return (operand1, operand2) -> new AtomicLong(operand1.longValue() * operand2.longValue());
}
#Override
public Function<AtomicLong, Long> finisher() {
return l -> l.longValue();
}
#Override
public Supplier<AtomicLong> supplier() {
return () -> new AtomicLong(1);
}
}
Testing this with what you've provided results in the correct answer, 8! = 40320.

I have a long time to stay at making some RxJava codes better to average some data

I have a collection of data like dummy below
class Place {
userId,
price
}
That means a collection of some places.
Use-case:
There is a user with userId and login.
How to calc average place-price that equal to userId ?
RxJava is nice and I have tried filter and toList, however it is not so performance nice.
Observable.fromIterable(places)
.subscribeOn(Schedulers.newThread())
.filter(new Predicate<Place>() {
#Override
public boolean test(Place place) throws Exception {
return place.userId == global.login.userId;
}
})
.toList()
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Consumer<List<Place>>() {
#Override
public void accept(List<Place> filteredPlace) throws Exception {
//Here I have to use loop to do math-average, it is not nice to average.
}
});
If the places is something that is already available in-memory, you can rearrange the evaluation such as this:
Observable.just(places)
.subscribeOn(Schedulers.computation())
.map((Iterable<Place> list) -> {
double sum = 0.0;
int count = 0;
for (Place p : list) {
if (p.userId == global.login.userId) {
sum += p.price;
count++;
}
}
return sum / count;
})
.observeOn(AndroidSchedulers.mainThread())
.subscribe(average -> { /* display average */ });
If the sequence of places becomes available over time (through an Observable):
Observable<Place> places = ...
places
.observeOn(Schedulers.computation())
.filter((Place p) -> p.userId == global.login.userId)
.compose(o -> MathObservable.averageDouble(o.map(p -> p.price)))
.observeOn(AndroidSchedulers.mainThread())
.subscribe(average -> { /* display average */ });
MathObservable is part of the RxJava 2 Extensions library.

How to walk binary abstract syntax tree to generate infix notation with minimally correct parentheses

I am being passed a binary AST representing a math formula. Each internal node is an operator and leaf nodes are the operands. I need to walk the tree and output the formula in infix notation. This is pretty easy to do by walking the tree with a recursive algorithm such as the Print() method shows below. The problem with the Print() method is that the order of operations is lost when converting to infix because no parentheses are generated.
I wrote the PrintWithParens() method which outputs a correct infix formula, however it adds extraneous parentheses. You can see in three of the four cases of my main method it adds parenthesis when none are necessary.
I have been racking my brain trying to figure out what the correct algorithm for PrintWithMinimalParens() should be. I'm sure there must be an algorithm that can output only parentheses when necessary to group terms, however I have been unable to implement it correctly. I think I must need to look at the precedence of the operators in the tree below the current node, but the algorithm I have there now does't work (see the last 2 cases in my main method. No parentheses are needed, but my logic adds them).
public class Test {
static abstract class Node {
Node left;
Node right;
String text;
abstract void Print();
abstract void PrintWithParens();
abstract void PrintWithMinimalParens();
int precedence()
{
return 0;
}
}
enum Operator {
PLUS(1,"+"),
MINUS(1, "-"),
MULTIPLY(2, "*"),
DIVIDE(2, "/"),
POW(3, "^")
;
private final int precedence;
private final String text;
private Operator(int precedence, String text)
{
this.precedence = precedence;
this.text = text;
}
#Override
public String toString() {
return text;
}
public int getPrecedence() {
return precedence;
}
}
static class OperatorNode extends Node {
private final Operator op;
OperatorNode(Operator op)
{
this.op = op;
}
#Override
void Print() {
left.Print();
System.out.print(op);
right.Print();
}
#Override
void PrintWithParens() {
System.out.print("(");
left.PrintWithParens();
System.out.print(op);
right.PrintWithParens();
System.out.print(")");
}
#Override
void PrintWithMinimalParens() {
boolean needParens =
(left.precedence() != 0 && left.precedence() < this.op.precedence)
||
(right.precedence() != 0 && right.precedence() < this.op.precedence);
if(needParens)
System.out.print("(");
left.PrintWithMinimalParens();
System.out.print(op);
right.PrintWithMinimalParens();
if(needParens)
System.out.print(")");
}
#Override
int precedence() {
return op.getPrecedence();
}
}
static class TextNode extends Node {
TextNode(String text)
{
this.text = text;
}
#Override
void Print() {
System.out.print(text);
}
#Override
void PrintWithParens() {
System.out.print(text);
}
#Override
void PrintWithMinimalParens() {
System.out.print(text);
}
}
private static void printExpressions(Node rootNode) {
System.out.print("Print() : ");
rootNode.Print();
System.out.println();
System.out.print("PrintWithParens() : ");
rootNode.PrintWithParens();
System.out.println();
System.out.print("PrintWithMinimalParens() : ");
rootNode.PrintWithMinimalParens();
System.out.println();
System.out.println();
}
public static void main(String[] args)
{
System.out.println("Desired: 1+2+3+4");
Node rootNode = new OperatorNode(Operator.PLUS);
rootNode.left = new TextNode("1");
rootNode.right = new OperatorNode(Operator.PLUS);
rootNode.right.left = new TextNode("2");
rootNode.right.right = new OperatorNode(Operator.PLUS);
rootNode.right.right.left = new TextNode("3");
rootNode.right.right.right = new TextNode("4");
printExpressions(rootNode);
System.out.println("Desired: 1+2*3+4");
rootNode = new OperatorNode(Operator.PLUS);
rootNode.left = new TextNode("1");
rootNode.right = new OperatorNode(Operator.PLUS);
rootNode.right.left = new OperatorNode(Operator.MULTIPLY);
rootNode.right.left.left = new TextNode("2");
rootNode.right.left.right = new TextNode("3");
rootNode.right.right = new TextNode("4");
printExpressions(rootNode);
System.out.println("Desired: 1+2*(3+4)");
rootNode = new OperatorNode(Operator.PLUS);
rootNode.left = new TextNode("1");
rootNode.right = new OperatorNode(Operator.MULTIPLY);
rootNode.right.left = new TextNode("2");
rootNode.right.right = new OperatorNode(Operator.PLUS);
rootNode.right.right.left = new TextNode("3");
rootNode.right.right.right = new TextNode("4");
printExpressions(rootNode);
System.out.println("Desired: 1+2^8*3+4");
rootNode = new OperatorNode(Operator.PLUS);
rootNode.left = new TextNode("1");
rootNode.right = new OperatorNode(Operator.MULTIPLY);
rootNode.right.left = new OperatorNode(Operator.POW);
rootNode.right.left.left = new TextNode("2");
rootNode.right.left.right = new TextNode("8");
rootNode.right.right = new OperatorNode(Operator.PLUS);
rootNode.right.right.left = new TextNode("3");
rootNode.right.right.right = new TextNode("4");
printExpressions(rootNode);
}
}
Output:
Desired: 1+2+3+4
Print() : 1+2+3+4
PrintWithParens() : (1+(2+(3+4)))
PrintWithMinimalParens() : 1+2+3+4
Desired: 1+2*3+4
Print() : 1+2*3+4
PrintWithParens() : (1+((2*3)+4))
PrintWithMinimalParens() : 1+2*3+4
Desired: 1+2*(3+4)
Print() : 1+2*3+4
PrintWithParens() : (1+(2*(3+4)))
PrintWithMinimalParens() : 1+(2*3+4)
Desired: 1+2^8*3+4
Print() : 1+2^8*3+4
PrintWithParens() : (1+((2^8)*(3+4)))
PrintWithMinimalParens() : 1+(2^8*3+4)
Is is possible to implement the PrintWithMinimalParens() that I want? Does the fact that order is implicit in the tree make doing what I want impossible?
In your code you are comparing each operator with its children to see if you need parentheses around it. But you should actually be comparing it with its parent. Here are some rules that can determine if parentheses can be omitted:
You never need parentheses around the operator at the root of the AST.
If operator A is the child of operator B, and A has a higher precedence than B, the parentheses around A can be omitted.
If a left-associative operator A is the left child of a left-associative operator B with the same precedence, the parentheses around A can be omitted. A left-associative operator is one for which x A y A z is parsed as (x A y) A z.
If a right-associative operator A is the right child of a right-associative operator B with the same precedence, the parentheses around A can be omitted. A right-associative operator is one for which x A y A z is parsed as x A (y A z).
If you can assume that an operator A is associative, i.e. that (x A y) A z = x A (y A z) for all x,y,z, and A is the child of the same operator A, you can choose to omit parentheses around the child A. In this case, reparsing the expression will yield a different AST that gives the same result when evaluated.
Note that for your first example, the desired result is only correct if you can assume that + is associative (which is true when dealing with normal numbers) and implement rule #5. This is because your input tree is built in a right-associative fashion, while operator + is normally left-associative.
You're enclosing an entire expression in parentheses if either the left or the right child has a lower-precedence operator even if one of them is a higher- or equal-precedence operator.
I think you need to separate your boolean needParens into distinct cases for the left and right children. Something like this (untested):
void PrintWithMinimalParens() {
boolean needLeftChildParens =
(left.precedence() != 0 && left.precedence() < this.op.precedence);
boolean needRightChildParens =
(right.precedence() != 0 && right.precedence() < this.op.precedence);
if(needLeftChildParens)
System.out.print("(");
left.PrintWithMinimalParens();
if(needLeftChildParens)
System.out.print(")");
System.out.print(op);
if(needRightChildParens)
System.out.print("(");
right.PrintWithMinimalParens();
if(needRightChildParens)
System.out.print(")");
}
Also, I don't think your last example is correct. Looking at your tree I think it should be:
1+2^8*(3+4)

Resources