From list <Foo> to Map <String, List <Foo>>: finding the best implementation
Let me show you my code:
Class foo
public class Foo { String code; String value; public Foo(String code, String value) { super(); this.code = code; this.value = value; } // getters/setters } Main method (focus on getFooMultiMapCode() method):
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 correctly prints this line:
{100=[foo1, foo4, foo5], 200=[foo2, foo6], 300=[foo3]} I would like to rewrite the getFooMultiMapCode method getFooMultiMapCode more succint way, using for example java8 or also libraries like lambdaj, guava, etc., but I don't want to change the method signature .
+7
user6904265
source share2 answers
Solution with Java 8 and groupingBy(classifier, downstream) :
return foos.stream().collect(Collectors.groupingBy(Foo::getCode, Collectors.toList())); Or just groupingBy(classifier) as @Boris the Spider noted:
return foos.stream().collect(Collectors.groupingBy(Foo::getCode)); +11
Andrew
source shareExpand the bit in the @Holgers comment: version without a stream, if you prefer loops - still java8 , though:
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; } or even
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; } I still prefer the stream version.
+1
Hulk
source share