We can do it in a single line of code using java 8
List<Long> ids = viewValues.stream().map(ViewValue::getId).collect(Collectors.toList());
For more info : Java 8 - Streams
Answer from Radhakrishna on Stack OverflowWe can do it in a single line of code using java 8
List<Long> ids = viewValues.stream().map(ViewValue::getId).collect(Collectors.toList());
For more info : Java 8 - Streams
You could do it in a one-liner using Commons BeanUtils and Collections:
(why write your own code when others have done it for you?)
import org.apache.commons.beanutils.BeanToPropertyValueTransformer;
import org.apache.commons.collections.CollectionUtils;
...
List<Long> ids = (List<Long>) CollectionUtils.collect(viewValues,
new BeanToPropertyValueTransformer("id"));
List<Value> list = new ArrayList<Value>(map.values());
assuming:
Map<Key,Value> map;
The issue here is that Map has two values (a key and value), while a List only has one value (an element).
Therefore, the best that can be done is to either get a List of the keys or the values. (Unless we make a wrapper to hold on to the key/value pair).
Say we have a Map:
Map<String, String> m = new HashMap<String, String>();
m.put("Hello", "World");
m.put("Apple", "3.14");
m.put("Another", "Element");
The keys as a List can be obtained by creating a new ArrayList from a Set returned by the Map.keySet method:
List<String> list = new ArrayList<String>(m.keySet());
While the values as a List can be obtained creating a new ArrayList from a Collection returned by the Map.values method:
List<String> list = new ArrayList<String>(m.values());
The result of getting the List of keys:
Apple Another Hello
The result of getting the List of values:
3.14 Element World
You just can use this:
List<CustomDataBean> result = origData.stream()
.collect(Collectors.groupingBy(DataBean::getEmployeeId))
.entrySet().stream()
.map(e -> new CustomDataBean(
e.getKey(),
e.getValue().stream().map(DataBean::getOrg).collect(Collectors.toList()),
e.getValue().get(0).getComments()))
.collect(Collectors.toList());
This maps the grouped results to your CustomDataBean object.
For the input:
List<DataBean> origData = Arrays.asList(
new DataBean(1, "a", "c"),
new DataBean(1, "b", "c"),
new DataBean(1, "c", "c"),
new DataBean(2, "a", "d"),
new DataBean(2, "c", "d")
);
The result will be this:
CustomDataBean[employeeId=1, orgs=[a, b, c], comments='c']
CustomDataBean[employeeId=2, orgs=[a, c], comments='d']
To answer both the questions, use Collectors.mapping as the downstream as :
Map<Integer, List<String>> temp = origData.stream().collect(
Collectors.groupingBy(DataBean::getEmployeeId,
Collectors.mapping(DataBean::getOrg, Collectors.toList())));
and further, achieve your goal to obtain a List<CustomDataBean> as:
List<CustomDataBean> goal = origData.stream()
.map(a -> new CustomDataBean(a.getEmployeeId(), temp.get(a.employeeId), a.getComments()))
.collect(Collectors.toList());
If you can expand your class to have a constructor taking the values as well:
map.entrySet()
.stream()
.map(e -> new PojoObject(e.getKey(), e.getValue()))
.collect(Collectors.toList());
If you can't:
map.entrySet()
.stream()
.map(e -> {
PojoObject po = new PojoObject();
po.setMapKey(e.getKey());
po.setMapValue(e.getValue());
return po;
}).collect(Collectors.toList());
Note that this uses Java 8 Stream API.
Looks like Java has exact POJO Map.Entry like you want. Hence, you can extract the entry set from map and iterate over the entry set like below or you can further convert the set to list like in next snippet and continue with your processing.
//fetch entry set from map
Set<Entry<String, String>> set = map.entrySet();
for(Entry<String, String> entry: set) {
System.out.println(entry.getKey() +"," + entry.getValue());
}
//convert set to list
List<Entry<String, String>> list = new ArrayList(set);
for(Entry<String, String> entry: list) {
System.out.println(entry.getKey() +"," + entry.getValue());
}
Would this work for you?
It requires a constructor for the target class but simply gets the values and creates an instance. Then it collects them to a list.
List<SomeClass> list = map.entrySet().stream()
.map(e -> new SomeClass(e.getKey(),
e.getValue().get(SomeEnum.BAR1),
e.getValue().get(SomeEnum.BAR2),
e.getValue().get(SomeEnum.BAR3)))
.collect(Collectors.toList());
Class with constructor
class SomeClass {
String name;
long bar1Value;
long bar2Value;
long bar3Value;
public SomeClass(String name, long bar1Value, long bar2Value,
long bar3Value) {
this.name = name;
this.bar1Value = bar1Value;
this.bar2Value = bar2Value;
this.bar3Value = bar3Value;
}
}
You could simplify the complete task with a utility to create SomeClass from the inner map:
private SomeClass createSomeClass(String name, Map<SomeEnum, Long> innerMap) {
return SomeClass.builder()
.name(name)
.bar1Value(innerMap.getOrDefault(SomeEnum.BAR1, 0L))
.bar2Value(innerMap.getOrDefault(SomeEnum.BAR2, 0L))
.bar3Value(innerMap.getOrDefault(SomeEnum.BAR3, 0L))
.build();
}
and then your mapping would be as easy as --
List<SomeClass> someClassList = map.entrySet().stream()
.map(e -> createSomeClass(e.getKey(), e.getValue()))
.collect(Collectors.toList());