java 8使用reduce和Collectors分组来获取列表 [英] java 8 use reduce and Collectors grouping by to get list
问题描述
编辑
**请求使用reduce方法提供第一种方法的答案**
EDIT **Request to provide answer to First approach also using reduce method **
public class Messages {
int id;
String message;
String field1;
String field2;
String field3;
int audId;
String audmessage;
//constructor
//getter or setters
}
public class CustomMessage {
int id;
String msg;
String field1;
String field2;
String field3;
List<Aud> list;
//getters and setters
}
public class Aud {
int id;
String message;
//getters and setters
}
public class Demo {
public static void main(String args[]){
List<Messages> list = new ArrayList<Messages>();
list.add(new Messages(1,"abc","c","d","f",10,"a1"));
list.add(new Messages(2,"ac","d","d","f",21,"a2"));
list.add(new Messages(3,"adc","s","d","f",31,"a3"));
list.add(new Messages(4,"aec","g","d","f",40,"a4"));
list.add(new Messages(1,"abc","c","d","f",11,"a5"));
list.add(new Messages(2,"ac","d","d","f",22,"a5"));
}
我希望用审计映射消息
CustomMessage必须有 - > 1,abc,c,d,f-----> 2个审核清单(10,a1)和(11,a5);
I want the message to be mapped with audits CustomMessage must have ->1,"abc","c","d","f"----->List of 2 audits (10,a1) and (11,"a5");
有两种方法可以做到这一点
There are two ways to do it
1.Reduce-我也想用reduce来创建我自己的累加器合并器
List<CustomMessage> list1= list.stream().reduce(new ArrayList<CustomMessage>(),
accumulator1,
combiner1);
**I am unable to write a accumulator and combiner**
2.Collectors.groupingBy -
- 我不想使用构造函数来创建消息和
都不是自定义消息。我有更少的字段我的实际对象有很多字段。任何方法都有一个静态
方法来创建对象 -
有没有办法通过写入累加器或
组合器来减少
- I do not want to use constructors for creating the Message and neither for Custom Message.here I have less fields my actual object has many fields.Any way to have a static method for object creation
Is there is a way to do it via reduce by writing accumulator or combiner
List<CustomMessage> l = list.stream()
.collect(Collectors.groupingBy(m -> new SimpleEntry<>(m.getId(), m.getMessage()),
Collectors.mapping(m -> new Aud(m.getAudId(), m.getAudMessage()), Collectors.toList())))
.entrySet()
.stream()
.map(e -> new CustomMessage(e.getKey().getKey(), e.getKey().getValue(), e.getValue()))
.collect(Collectors.toList());
任何人都可以帮助我解决这两种方法。
Can anyone help me with both the approaches.
推荐答案
此代码将创建一个 Collection
CUSTOMMESSAGE
。我建议在 CustomMessage
中放置一个带有 Messages
参数的构造函数。也许还可以将mergeFunction移出 collect
。
This code will create a Collection
of CustomMessage
. I would recommend putting a constructor in CustomMessage
that takes a Messages
argument. And maybe also move the mergeFunction out of the collect
.
Collection<CustomMessage> customMessages = list.stream()
.collect(toMap(
Messages::getId,
m -> new CustomMessage(m.getId(), m.getMessage(), m.getField1(), m.getField2(), m.getField3(),
new ArrayList<>(singletonList(new Aud(m.getAudId(), m.getAudmessage())))),
(m1, m2) -> {
m1.getList().addAll(m2.getList());
return m1;
}))
.values();
toMap 这里是:第一次遇到消息
id
时,它会把它作为键放到Map上带有值的新创建的 CustomMessage
,第二个参数为 toMap
(valueMapper )。接下来它将合并两个 CustomMessage
与第三个参数mergeFunction,它将有效地连接2个列表Aud
。
What toMap does here is : The first time a Messages
id
is encountered, it will put it to a Map as key with value the newly created CustomMessage
by the second argument to toMap
(the "valueMapper"). The next times it will merge two CustomMessage
with the 3rd argument the "mergeFunction" that will effectively concatenate the 2 lists of Aud
.
如果你绝对需要 List
而不是 Collection
:
And if you absolutely need a List
and not a Collection
:
List<CustomMessage> lm = new ArrayList<>(customMessages);
这篇关于java 8使用reduce和Collectors分组来获取列表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!