[英]Get Map<String, List<Object>> from List<Object> where the key is one of the fields of the objects
I've got an object as below我有一个 object 如下
public class Model {
private String key;
private String data1;
private String data2;
private String data3;
// getters
}
A list of these Models is being returned via the data layer.这些模型的列表正在通过数据层返回。 Now I want to create a Map<String, List<Model>>
with the key being the "key" field in the Model
class.现在我想创建一个Map<String, List<Model>>
,其键是Model
class 中的“键”字段。 There are multiple duplicate "key"s with different data values.有多个具有不同数据值的重复“键”。 I have the below existing solution but need a simpler and better way.我有以下现有解决方案,但需要一种更简单更好的方法。 Haven't used Java 8 extensively so not quite familiar with most of the methods and need a solution soon as I don't have time to research.没有广泛使用 Java 8 所以对大多数方法不太熟悉,并且由于我没有时间研究而需要尽快解决。
List<Model> models = modelRepo.getAllModels();
Set<String> keys = models.stream().map(Model::getKey).collect(Collectors.toSet());
Map<String, List<Model>> result = new HashMap<>();
keys.stream().forEach(key -> {
List<Model> modelList = new ArrayList<>();
models.stream().forEach(model -> {
if (model.getKey().equals(key)) {
modelList.add(model);
}
});
result.put(key, modelList);
});
Use groupingBy
for grouping Models by key
which return Map使用groupingBy
按返回 Map 的key
对模型进行分组
Map<String, List<Model>> results = models.stream()
.collect(Collectors.groupingBy(Model::getKey));
groupingBy
method which only takes a function as its parameter. groupingBy
方法,仅以 function 作为其参数。 The value that is returned by the function is used as a key to the map that we get from the groupingBy collector. function 返回的值用作我们从 groupingBy 收集器获得的 map 的键。
First of all, stream().forEach()
can be replaced with forEach()
as long as no intermediate operations are used.首先,只要不使用中间操作, stream().forEach()
可以替换为forEach()
。
What you want is a typical use-case for Collectors.groupingBy
with no further downstream collector:您想要的是Collectors.groupingBy
的典型用例,没有进一步的下游收集器:
Map<String, List<Model>> result = models.stream() // Stream<Model>
.collect(Collectors.groupingBy(Model::getKey)); // Map<String, List<Model>>
You can use groupingBy:您可以使用 groupingBy:
public class Test1 {
public static void main(String[] args) {
List<Model> models = new ArrayList<>();
models.add(new Model("a", "a1", "a2", "a3"));
models.add(new Model("a", "a4", "a5", "a6"));
models.add(new Model("c", "c1", "c2", "c3"));
models.add(new Model("d", "d1", "d2", "d3"));
models.add(new Model("d", "d4", "d5", "d6"));
Map<String, List<Model>> result = models.stream().collect(Collectors.groupingBy(Model::getKey));
result.forEach((a, b) -> System.out.println(a + " - " + b));
}
public static class Model {
private String key;
private String data1;
private String data2;
private String data3;
public Model(String key, String data1, String data2, String data3) {
this.key = key;
this.data1 = data1;
this.data2 = data2;
this.data3 = data3;
}
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
}
public String getData1() {
return data1;
}
public void setData1(String data1) {
this.data1 = data1;
}
public String getData2() {
return data2;
}
public void setData2(String data2) {
this.data2 = data2;
}
public String getData3() {
return data3;
}
public void setData3(String data3) {
this.data3 = data3;
}
@Override
public String toString() {
return "Model{" +
"key='" + key + '\'' +
", data1='" + data1 + '\'' +
", data2='" + data2 + '\'' +
", data3='" + data3 + '\'' +
'}';
}
}
}
Well for starters, the elegant way is that you can use the groupBy
in stream()
.对于初学者来说,优雅的方式是您可以在stream()
中使用groupBy
。
Map<String, List<Model>> results = models.stream()
.collect( Collectors.groupingBy(Model::getKey));
And if you are reluctant to use stream()
, And also since you mention that you haven't used Java 8 extensively so not quite familiar with most of the methods.如果您不愿意使用stream()
,而且由于您提到您没有广泛使用 Java 8 ,因此对大多数方法不太熟悉。 There's always the traditional way of doing this with loops.使用循环总是有传统的方法。
Map<String,List<Model>> results = new HashMap<>( );
for( Model m : models )
{
if( results.containsKey( m.getKey() ) )
{
results.get( m.getKey() ).add( m );
}
else
{
results.put( m.getKey(), new ArrayList<>( Collections.singleton(m) ) );
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.