Two separate stream operations merged into one [duplicate] - java

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

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+

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

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

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

Modify part of the list and then return the updated list [duplicate]

This question already has an answer here:
how to keep the unfiltered data in the collection in Java 8 Streaming API?
(1 answer)
Closed 7 years ago.
I am playing with Java 8 and trying to work with stream(). What I want to achieve is say, I have a list [1,2,3,4], I want to double the even numbers 2 and 4 and then return the list with the updated values. So, I will get [1,4,3,8] as a result. I tried the following but it only returned [4,8].
List<Integer> myList =
Arrays.asList(1,2,3,4);
myList = myList
.stream()
.filter(n -> n%2==0)
.map(n -> n*2)
.collect(Collectors.toList());
System.out.println(myList);
Is there a way to do what I want?
The filter method removes those elements that don't fit the condition. It does not make the rest of the operations not applicable. Move the condition inside your map method.
myList = myList
.stream()
.map(n -> (n % 2 == 0) ? n*2 : n)
.collect(Collectors.toList());

Categories