Collection<Map<String, MyObj>>
I need to collect list of MyObj from above structure.
For instance I also had Collection<MyObj> - in this for collecting list of MyObj I did below
List<MyObj> result = new ArrayList<>(MyObj);
works fine.
How do I achieve similar result from Collection<Map<String, MyObj>>?
So you want to flatten the maps to a single list of values? You can use streams to do this pretty easily:
List<MyObj> list = collection.stream()
.map(Map::values)
.flatMap(Collection::stream)
.collect(Collectors.toList());
You can do:
List<MyObj> result = collections.stream()
.flatMap(m->m.values().stream())
.collect(toList());
Try this:
Takes the map values and streams them and collects them into a list.
List<MyObj> obList = origList.stream()
.flatMap(m->m.values().stream())
.collect(Collectors.toList());
Related
I have a Object with multiple properties and I want to add multiple properties to same list
I was able to add one property couldn't find a way to add other property.
Can we do that if yes how ?
List<MyObject> myObject = new ArrayList<>();
I have some values in the object here
List<Long> Ids = myObject .stream().map(MyObject::getJobId).collect(Collectors.toList());
here I want to add one more property from same MyObject object getTestId to the list is there a way that I can add with in the same above statement ?
Create two lists using the streams then combine them in the end, map can only return one value either getJobId or getTestId, so you can't do it in the same iteration.
List<Long> JobIds = myObject.stream().map(myObj::getJobId).collect(Collectors.toList());
List<Long> TestIds = myObject.stream().map(myObj::getTestId).collect(Collectors.toList());
List<Long> Ids = Stream.concat(JobIds.stream(), TestIds.stream()).collect(Collectors.toList());
If you want a list containing the jobIds and the testIds then you can use something like this:
List<Long> ids = new ArrayList<>();
myObject.forEach(o -> {
ids.add(o.getJobId());
ids.add(o.getTestId());
});
In .map operation the object should be mapped to a list/stream of required ids and then apply flatMap:
List<Long> ids = myObject
.stream()
.map(mo -> Arrays.asList(mo.getId(), mo.getTestId()))
.flatMap(List::stream)
.collect(Collectors.toList());
or (same as Holger's comment)
List<Long> ids = myObject
.stream()
.flatMap(mo -> Stream.of(mo.getId(), mo.getTestId()))
.collect(Collectors.toList());
If the ids should be followed by testIds, the streams may be concatenated:
List<Long> ids = Stream.concat(
myObject.stream().map(MyObject::getId),
myObject.stream().map(MyObject::getTestId)
)
.collect(Collectors.toList());
If more than two properties should be listed one after another, Stream.of + flatMap should be used:
List<Long> ids = Stream.of(
myObject.stream().map(MyObject::getId),
myObject.stream().map(MyObject::getTestId),
myObject.stream().map(MyObject::getAnotherId)
)
.flatMap(Function.identity())
.collect(Collectors.toList());
I am new to Java streams and have a problem at hand. I have a map like this:
Map<String, List<String>> specialProductsMap
And i want to flatten the map values to a set which contains all the String values in lists in the specialProductsMap. How can i do this using Java Streams?
You may use the flatMap operator to get this thing done. Here's how it looks.
Set<String> valueSet = specialProductsMap.values().stream()
.flatMap(List::stream)
.collect(Collectors.toSet());
First Obtain the list of values from map then use stream api like this
Set<String> setOfString = specialProductsMap.values().stream().flatMap(list->list.stream())
.collect(Collectors.toSet());
Or Like this Using Method reference
Set<String> setOfString = specialProductsMap.values().stream().flatMap(List::stream)
.collect(Collectors.toSet());
You have to stream your values :
Stream<List<String>> myStream = specialProductsMap.values().stream();
Then flatten it :
Stream<String> myData = myStream.flatMap(List::stream);
Then collect in a set :
Set<String> = myData.collect(Collectors.toSet());
I have a Data structure - ArrayList> and this is what I need to do -
ArrayList<HashMap<String, String>> optMapList;
//populated optMapList with some code. Not to worry abt this
List<String> values = new ArrayList<String>();
for(HashMap<String,String> entry: optMapList){
values.add(entry.get("optValue"));
}
How do we use Java Streams to achieve the same objective?
optMapList.stream()
.filter(Objects:nonNull) // potentially filter null maps
.map(m -> m.get("optValue"))
.filter(Objects::nonNull) // potentially filter null values form the map
// .collect(Collectors.toCollection(ArrayList::new))
.collect(Collectors.toList())
I have a Map<String, List<String>>. I want to transform this map to a List after filtering on the map's key.
Example:
Map<String, List<String>> words = new HashMap<>();
List<String> aList = new ArrayList<>();
aList.add("Apple");
aList.add("Abacus");
List<String> bList = new ArrayList<>();
bList.add("Bus");
bList.add("Blue");
words.put("A", aList);
words.put("B", bList);
Given a key, say, "B"
Expected Output: ["Bus", "Blue"]
This is what I am trying:
List<String> wordsForGivenAlphabet = words.entrySet().stream()
.filter(x-> x.getKey().equalsIgnoreCase(inputAlphabet))
.map(x->x.getValue())
.collect(Collectors.toList());
I am getting an error. Can someone provide me with a way to do it in Java8?
Your sniplet wil produce a List<List<String>> not List<String>.
You are missing flatMap , that will convert stream of lists into a single stream, so basically flattens your stream:
List<String> wordsForGivenAlphabet = words.entrySet().stream()
.filter(x-> x.getKey().equalsIgnoreCase(inputAlphabet))
.map(Map.Entry::getValue)
.flatMap(List::stream)
.collect(Collectors.toList());
You can also add distinct(), if you don't want values to repeat.
Federico is right in his comment, if all you want is to get the values of a certain key (inside a List) why don't you simply do a get (assuming all your keys are uppercase letters already) ?
List<String> values = words.get(inputAlphabet.toUpperCase());
If on the other hand this is just to understand how stream operations work, there is one more way to do it (via java-9 Collectors.flatMapping)
List<String> words2 = words.entrySet().stream()
.collect(Collectors.filtering(x -> x.getKey().equalsIgnoreCase(inputAlphabet),
Collectors.flatMapping(x -> x.getValue().stream(),
Collectors.toList())));
As was previously told after collect you will get List<List<String>> with only one or zero value in it. You can use findFirst instead of collect it will return you Optional<List<String>>.
How this can be replaced with collect?
List<Serializable> result = new ArrayList<>();
entries.forEach(entry-> result.add(session.save(entry)));
That's pretty straight forward :
List<Serializable> result =
entries.stream()
.map(session::save)
.collect(Collectors.toList());
The map method maps the input entries into Serializable instances by calling session::save, and then all you need to do is collect them to a List.