Underlay another Optional in stream if current is not present [duplicate] - java

This question already has answers here:
Chaining Optionals in Java 8
(10 answers)
Closed 2 years ago.
public static BigDecimal calculateSomething(List<Type> myList, Optional<Type> secondOne) {
return myList.stream()
.findFirst()
.map(x -> x.getBalance().subtract(x.getAmount()))
.orElse(secondOne.map(x -> x.getBalance().subtract(x.getAmount()))
.orElse(BigDecimal.ZERO));
}
I want to do some mapping on firstOne from myList if it's present. If it's not I want to do same thing on the secondOne. If it's not present either then return ZERO.
Is there a way to write this inside of one stream and reduce code duplication and stream inside of the stream on Optional?

Yep:
return myList.stream().findFirst()
.or(() -> secondOne)
.map(x -> x.getBalance().subtract(x.getAmount()))
.orElse(BigDecimal.ZERO));

Related

Get all indexes of an array with a certain condition in java [duplicate]

This question already has answers here:
Find all indexes of a value in a List [duplicate]
(3 answers)
Closed 12 days ago.
I have a list of strings and I want to add to a set all indexes from array where the string is not empty,
I tried doing this:
columnNum.addAll((Collection<? extends Integer>) IntStream.range(0, row.size()).filter(i-> StringUtils.isNotEmpty(row.get(i))));
but I get an exception
You have to use boxed:
var list = List.of("","a","","b");
var set = IntStream.range(0, list.size())
.filter(i ->
!list.get(i).isEmpty()).boxed().collect(Collectors.toSet());
Collect the stream to a List first. An IntStream is not a Collection.
columnNum.addAll(IntStream.range(0, row.size())
.filter(i-> StringUtils.isNotEmpty(row.get(i)))
.boxed().collect(Collectors.toList())); // or .toList() with Java 16+

Two separate stream operations merged into one [duplicate]

This question already has answers here:
How to force max to return ALL maximum values in a Java Stream?
(9 answers)
Closed 2 years ago.
Is it possible (or even viable) to merge these two stream operations into a single pass solution?
int max = locations.stream()
.map(location -> location.getAvailableScooters().size())
.max(Comparator.naturalOrder())
.orElse(-1);
return locations.stream()
.filter(location -> location.getAvailableScooters().size() == max)
.collect(Collectors.toSet());
The only way I see the merging is possible is like this:
return locations.stream()
.filter(location -> location.getAvailableScooters().size() ==
locations.stream()
.map(location -> location.getAvailableScooters().size())
.max(Comparator.naturalOrder())
.orElse(-1) )
.collect(Collectors.toSet());
which is a much worse solution
max and collect are both terminal operations which makes the merging impossible

Collect map from other map by stream [duplicate]

This question already has answers here:
Java 8 stream map on entry set
(6 answers)
Closed 3 years ago.
I have such code:
Map<Integer, Settings> operatorsSettings = new HashMap<>();
operators.forEach((operator, codeTypes) -> operatorsSettings.put(operator, mapper.convertValue(codeTypes.get(SETTINGS), Settings.class)));
return operatorsSettings;
I wrote it but i wonder. Is it possible to write it without creating a new map. Something like this (not correct code):
return operators.entrySet().stream()
.collect(entry -> Collectors.toMap(entry.getKey() , mapper.convertValue(entry.getValue().get(SETTINGS), Settings.class)));
It is possible, you just made a small syntax mistake...
return operators.entrySet().stream().collect(Collectors.toMap(entry -> entry.getKey() , mapper.convertValue(entry.getValue().get(SETTINGS), Settings.class)));
Yes, you can do this in plain java:
return operators.entrySet().stream()
.collect(Collectors.toMap(entry -> entry.getKey() , entry -> mapper.convertValue(entry.getValue().get(SETTINGS), Settings.class)));
or you can use streamex library and write it like this:
EntryStream.of(operatorsSettings).mapValues(codeTypes -> mapper.convertValue(codeTypes.get(SETTINGS), Settings.class))...

Java 8 Map not being sorted by value properly [duplicate]

This question already has answers here:
Java 8 is not maintaining the order while grouping
(2 answers)
Stream doesn't preserve the order after grouping
(3 answers)
Closed 4 years ago.
I've read many questions regarding Java 8 and Collections on this site and, given my limited understanding of java streams, I'm having some trouble trying to sort this Map.
My code is as follows, being tradeList an ArrayList();
Map<String, Double> buyReport = tradeList.stream().filter(trade -> trade.getInstruction() == Instruction.BUY)
.sorted(Comparator.comparing(trade -> trade.getInstructionDate()))
.collect(Collectors.groupingBy(trade -> dateFormat.format(trade.getInstructionDate()),
Collectors.summingDouble(trade -> trade.getUSDAmount())));
Does it make any sense to include the .sorted() statement when composing a HashMap? I tried to create a LinkedHashmap, use a custom comparator for the value i need the object instances to compare (a Double), but to no avail.
I can include any other piece of code you may find useful.
Thanks in advance!!
Update: tried this recently; still getting results unordered when grouping by company code and then summing company totals:
Map<String, Double> entityOutgoingReport = tradeList.stream()
.filter(trade -> trade.getInstruction() == Instruction.SELL)
.collect(Collectors.groupingBy(trade -> String.valueOf(trade.getEntity()),
LinkedHashMap::new,
Collectors.summingDouble(trade -> trade.getUSDAmount())));
for (String entity : entityOutgoingReport.keySet()) {
String key = entity;
String value = decFormat.format(entityOutgoingReport.get(entity));
tableBuilder.addRow(key, value); //Just pretty printing to console
}
Simply supply a LinkedHashMap into which the results will be inserted therefore maintaining order.
.collect(Collectors.groupingBy(trade ->
dateFormat.format(trade.getInstructionDate()),
LinkedHashMap::new,
Collectors.summingDouble(trade -> trade.getUSDAmount())));
Full code:
Map<String, Double> entityOutgoingReport =
tradeList.stream()
.filter(trade -> trade.getInstruction() == Instruction.SELL)
.sorted(Comparator.comparing(trade -> trade.getInstructionDate()))
.collect(Collectors.groupingBy(trade -> String.valueOf(trade.getEntity()),
LinkedHashMap::new,
Collectors.summingDouble(trade -> trade.getUSDAmount())));

How to collect the elements of a Stream into a Queue? [duplicate]

This question already has answers here:
Collection to stream to a new collection
(4 answers)
Closed 6 years ago.
I have the following code:
Queue<Reward> possibleRewards =
Stream.of(Reward.values())
.flatMap(reward -> IntStream.range(0, reward.getOccurencies()).mapToObj(i -> reward))
.collect(Collectors.toList());
As you can see, I need to collect the elements of the Stream into a Queue, not a List. However, there's no Collectors.toQueue() method. How can I collect the elements into a Queue?
You can use Collectors.toCollection(), which lets you choose whatever Collection implementation you wish to produce:
Queue<Reward> possibleRewards =
Stream.of(Reward.values())
.flatMap(reward -> IntStream.range(0, reward.getOccurencies()).mapToObj(i -> reward))
.collect(Collectors.toCollection(PriorityQueue::new)); // use whatever Queue
// implementation you want
Queue<Reward> possibleRewards = new LinkedBlockingQueue<>(); //Or whichever type of queue you would like
possibleRewards.addAll(Stream.of(Reward.values())
.flatMap(reward -> IntStream.range(0, reward.getOccurencies()).mapToObj(i -> reward))
.collect(Collectors.toList()));

Categories