gpt4 book ai didi

Java 流 : Add to map but avoid mutation

转载 作者:搜寻专家 更新时间:2023-10-31 19:31:57 24 4
gpt4 key购买 nike

我经常发现自己需要创建一个 Map来自 Set 或 List 的对象.键通常是一些 String 或 Enum 等,而值是一些新对象,其中包含一些数据。就我而言,通常的做法是首先创建 Map<String, SomeKeyValueObject>然后迭代我进入的 Set 或 List 并改变我新创建的 map 。

像下面的例子:

class Example {
Map<String, GroupedDataObject> groupData(final List<SomeData> list){
final Map<String, GroupedDataObject> map = new HashMap<>();
for(final SomeData data : list){
final String key = data.valueToGroupBy();
map.put(key, GroupedDataObject.of(map.get(key), data.displayName(), data.data()));
}
return map;
}

}

class SomeData {
private final String valueToGroupBy;
private final Object data;
private final String displayName;

public SomeData(final String valueToGroupBy, final String displayName, final Object data) {
this.valueToGroupBy = valueToGroupBy;
this.data = data;
this.displayName = displayName;
}

public String valueToGroupBy() {
return valueToGroupBy;
}

public Object data() {
return data;
}

public String displayName() {
return displayName;
}
}

class GroupedDataObject{

private final String key;
private final List<Object> datas;

private GroupedDataObject(final String key, final List<Object> list) {
this.key = key;
this.datas = list;
}

public static GroupedDataObject of(final GroupedDataObject groupedDataObject, final String key, final Object data) {
final List<Object> list = new ArrayList<>();
if(groupedDataObject != null){
list.addAll(groupedDataObject.datas());
}
list.add(data);
return new GroupedDataObject(key, list);
}

public String key() {
return key;
}

public List<Object> datas() {
return datas;
}
}

这感觉很不干净。我们创建一个 map ,然后一遍又一遍地改变它。

我喜欢 java 8s 使用 Stream s 并创建非变异数据结构(或者更确切地说,您看不到变异)。那么有没有一种方法可以将这种数据分组变成使用声明式方法而不是命令式方法的东西?

我尝试执行 https://stackoverflow.com/a/34453814/3478016 中的建议但我似乎绊倒了。使用答案中的方法(使用 Collectors.groupingByCollectors.mapping 的建议)我能够将数据分类到 map 中。但我无法将“数据”归为同一个对象。

有没有什么方法可以用声明的方式做到这一点,或者我是否坚持命令式?

最佳答案

您可以使用带有合并功能的 Collectors.toMap 而不是 Collectors.groupingBy

Map<String, GroupedDataObject> map =
list.stream()
.collect(Collectors.toMap(SomeData::valueToGroupBy,
d -> {
List<Object> l = new ArrayList<>();
l.add(d.data());
return new GroupedDataObject(d.valueToGroupBy(), l);
},
(g1,g2) -> {
g1.datas().addAll(g2.datas());
return g1;
}));

GroupedDataObject 构造函数必须可访问才能使其工作。

关于Java 流 : Add to map but avoid mutation,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47690553/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com