Java 8 - How to search a MultiValueMap with value? [duplicate] - java

This question already has answers here:
Create only 1 list from a map where map value is list using JAVA 8 Streams
(3 answers)
Closed 4 years ago.
I have a
MultiValueMap<String, String> map = new LinkedMultiValueMap<>();
The type of value is a list of strings:
List<String> valueList = map.get('key');
How can i search through this map (through all the valueLists within this map) and get all the values which startsWith 'xy' in a list back?
I hope the question is clear.
I have tried this, but no success:
map
.entrySet()
.stream()
.filter(e-> e.getValue().stream().filter(value -> value.startsWith(searchString)))
.collect(Collectors.toList());
I get this error: Stream cannot be converted to boolean

If I understood your problem correctly:
map.values()
.stream()
.flatMap(List::stream)
.filter(x -> x.startsWith(searchString))
.collect(Collectors.toList())

Related

how to collect to LinkedHashMap in java 8 [duplicate]

This question already has answers here:
Transform a List<Object> to a Map<String, Integer> such that the String is not a duplicate value using Java 8 Streams
(4 answers)
Closed 2 years ago.
Currently we are converting list returned by repository.findAll() into the Map by doing:
Map<Long, FooDto> fooMap=fooRepository.findAll()
.stream()
.map(fooDomainToDtoMapper::mapDomainToDto)
.collect(Collectors.toMap(fooDto::getfooId, foo -> foo));
But we want to preserve the order returned by the repository.findAll(). We want to return the records in the descending order and then collect it to the LinkedHashmap by doing something like :
Map<Long, FooDto> fooMap= fooRepository.findAll(Sort.by(Sort.Direction.DESC, "name"))
.stream()
.map(fooDomainToDtoMapper::mapDomainToDto)
//trying to do something like:
.collect(Collectors.toMap(fooDto::getfooId, foo -> foo,LinkedHashMap::new));
If we try to collect the above descending order result in the normal Collectors.toMap then sorted query has no effect at all, it is looking like normal select in the final result.
If you want to pass a supplier for the Map, you must pass a merge function too:
Map<Long, FooDto> fooRepository.findAll(Sort.by(Sort.Direction.DESC, "name"))
.stream()
.map(fooDomainToDtoMapper::mapDomainToDto)
.collect(Collectors.toMap(fooDto::getfooId,
Function.identity(),
(v1,v2)->v1,
LinkedHashMap::new));
Try this:
.stream()
.map(fooDomainToDtoMapper::mapDomainToDto)
.collect(LinkedHashMap::new,
(map, fooDto) -> map.put(fooDto.getfooId(), fooDto),
Map::putAll);

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 add values from Map<T,List<L>> map to List<L>? [duplicate]

This question already has answers here:
Convert List of List into list in java
(5 answers)
Closed 5 years ago.
I have a multimap Map<T,List<L>> map and I need a list with all the values of the values from the map, namely List<L>. With map.values() I get a List<List<L>>, but thats not what I want.
Does someone know a clean solution without looping?
If you are using Java 8, you could collect all L values from all List<L>s in a single List<L> by Stream#flatMap:
final List<L> list = map
// get a Collection<List<L>>
.values()
// make a stream from the collection
.stream()
// turn each List<L> into a Stream<L> and merge these streams
.flatMap(List::stream)
// accumulate the result into a List
.collect(Collectors.toList());
Otherwise, a for-each approach with Collection#addAll can be applied:
final List<L> list = new ArrayList<>();
for (final List<L> values : map.values()) {
list.addAll(values);
}

Transform to map with predictable order [duplicate]

This question already has answers here:
Java 8 Collectors.toMap SortedMap
(5 answers)
Closed 7 years ago.
I have following code:
users.stream()
.sorted((u1, u2) -> u2.getScore().compareTo(u1.getScore()))
.limit(count)
.collect(Collectors.toMap((User::getName), (User::getScore)));
Content of result is right but when I want to foreach it - it output in unpredictable result. I think it is because under the hood HashMap is used.
Is there way to collect to mp with predictable result?
This works:
return users.stream()
.sorted((u1, u2) -> u2.getScore().compareTo(u1.getScore()))
.limit(count)
.collect(Collectors.toMap((User::getName), (User::getScore), (k, v) -> {
throw new RuntimeException(String.format("Duplicate key %s", k));
},
LinkedHashMap::new));

Categories