从 List<Foo> 到 Map<String, List<Foo>>:寻找更好的实现
From List<Foo> to Map<String, List<Foo>>: looking for a better implementation
让我给你看我的代码:
Class 富
public class Foo {
String code;
String value;
public Foo(String code, String value) {
super();
this.code = code;
this.value = value;
}
// getters/setters
}
主要方法(关注getFooMultiMapCode()
方法):
public class FooMain {
public static void main(String[] args) {
Foo foo1 = new Foo("100","foo1");
Foo foo2 = new Foo("200","foo2");
Foo foo3 = new Foo("300","foo3");
Foo foo4 = new Foo("100","foo4");
Foo foo5 = new Foo("100","foo5");
Foo foo6 = new Foo("200","foo6");
List<Foo> foos = Arrays.asList(foo1,foo2,foo3,foo4,foo5,foo6);
Map<String,List<Foo>> fooCodeMap = getFooMultiMapCode(foos);
System.out.println(fooCodeMap);
}
private static Map<String, List<Foo>> getFooMultiMapCode(List<Foo> foos) {
Map<String, List<Foo>> fooMultiMapCode = new HashMap<String, List<Foo>>();
for(Foo foo:foos){
List<Foo> list = fooMultiMapCode.get(foo.getCode());
if(list==null){
list = new ArrayList<Foo>();
list.add(foo);
fooMultiMapCode.put(foo.getCode(), list);
}
else {
list.add(foo);
}
}
return fooMultiMapCode;
}
}
Main 正确打印此字符串:
{100=[foo1, foo4, foo5], 200=[foo2, foo6], 300=[foo3]}
我想以更简洁的方式重写 getFooMultiMapCode
方法,例如使用 java8 或 lambdaj、guava 等库,但我 不想更改方法签名.
Java 8 和 groupingBy(classifier, downstream)
的解决方案:
return foos.stream().collect(Collectors.groupingBy(Foo::getCode, Collectors.toList()));
或者只是注意到groupingBy(classifier)
as @Boris the Spider:
return foos.stream().collect(Collectors.groupingBy(Foo::getCode));
扩展一下@Holgers 的评论:非流版本如果你喜欢循环 - 仍然 java8
,但是:
private static Map<String, List<Foo>> getFooMultiMapCode(List<Foo> foos) {
Map<String, List<Foo>> fooMultiMapCode = new HashMap<String, List<Foo>>();
for(Foo foo : foos){
fooMultiMapCode.computeIfAbsent(foo.getCode(), x -> new ArrayList<>()).add(foo);
}
return fooMultiMapCode;
}
甚至
private static Map<String, List<Foo>> getFooMultiMapCode(List<Foo> foos) {
Map<String, List<Foo>> fooMultiMapCode = new HashMap<String, List<Foo>>();
foos.forEach(foo -> fooMultiMapCode.computeIfAbsent(foo.getCode(), x -> new ArrayList<>()).add(foo));
return fooMultiMapCode;
}
不过我还是更喜欢流媒体版本。
让我给你看我的代码:
Class 富
public class Foo {
String code;
String value;
public Foo(String code, String value) {
super();
this.code = code;
this.value = value;
}
// getters/setters
}
主要方法(关注getFooMultiMapCode()
方法):
public class FooMain {
public static void main(String[] args) {
Foo foo1 = new Foo("100","foo1");
Foo foo2 = new Foo("200","foo2");
Foo foo3 = new Foo("300","foo3");
Foo foo4 = new Foo("100","foo4");
Foo foo5 = new Foo("100","foo5");
Foo foo6 = new Foo("200","foo6");
List<Foo> foos = Arrays.asList(foo1,foo2,foo3,foo4,foo5,foo6);
Map<String,List<Foo>> fooCodeMap = getFooMultiMapCode(foos);
System.out.println(fooCodeMap);
}
private static Map<String, List<Foo>> getFooMultiMapCode(List<Foo> foos) {
Map<String, List<Foo>> fooMultiMapCode = new HashMap<String, List<Foo>>();
for(Foo foo:foos){
List<Foo> list = fooMultiMapCode.get(foo.getCode());
if(list==null){
list = new ArrayList<Foo>();
list.add(foo);
fooMultiMapCode.put(foo.getCode(), list);
}
else {
list.add(foo);
}
}
return fooMultiMapCode;
}
}
Main 正确打印此字符串:
{100=[foo1, foo4, foo5], 200=[foo2, foo6], 300=[foo3]}
我想以更简洁的方式重写 getFooMultiMapCode
方法,例如使用 java8 或 lambdaj、guava 等库,但我 不想更改方法签名.
Java 8 和 groupingBy(classifier, downstream)
的解决方案:
return foos.stream().collect(Collectors.groupingBy(Foo::getCode, Collectors.toList()));
或者只是注意到groupingBy(classifier)
as @Boris the Spider:
return foos.stream().collect(Collectors.groupingBy(Foo::getCode));
扩展一下@Holgers 的评论:非流版本如果你喜欢循环 - 仍然 java8
,但是:
private static Map<String, List<Foo>> getFooMultiMapCode(List<Foo> foos) {
Map<String, List<Foo>> fooMultiMapCode = new HashMap<String, List<Foo>>();
for(Foo foo : foos){
fooMultiMapCode.computeIfAbsent(foo.getCode(), x -> new ArrayList<>()).add(foo);
}
return fooMultiMapCode;
}
甚至
private static Map<String, List<Foo>> getFooMultiMapCode(List<Foo> foos) {
Map<String, List<Foo>> fooMultiMapCode = new HashMap<String, List<Foo>>();
foos.forEach(foo -> fooMultiMapCode.computeIfAbsent(foo.getCode(), x -> new ArrayList<>()).add(foo));
return fooMultiMapCode;
}
不过我还是更喜欢流媒体版本。