I want to group elements of a list. I’m currently doing it this way:
public static <E> List<List<E>> group(final List<E> list, final GroupFunction<E> groupFunction) {
List<List<E>> result = Lists.newArrayList();
for (final E element : list) {
boolean groupFound = false;
for (final List<E> group : result) {
if (groupFunction.sameGroup(element, group.get(0))) {
group.add(element);
groupFound = true;
break;
}
}
if (! groupFound) {
List<E> newGroup = Lists.newArrayList();
newGroup.add(element);
result.add(newGroup);
}
}
return result;
}
public interface GroupFunction<E> {
public boolean sameGroup(final E element1, final E element2);
}
Is there a better way to do this, preferably by using guava?
Sure it is possible, and even easier with Guava 🙂 Use
Multimaps.index(Iterable, Function):If you give concrete use case it would be easier to show it in action.
Example from docs:
prints
In your case if GroupFunction is defined as:
then it would translate to:
which is possible
stringLengthFunctionimplementation used in Guava’s example.Finally, in Java 8, whole snippet could be even simpler, as lambas and method references are concise enough to be inlined:
For pure Java 8 (no Guava) example using
Collector.groupingBysee Jeffrey Bosboom’s answer, although there are few differences in that approach:ImmutableListMultimapbut ratherMapwithCollectionvalues,EDIT: If you don’t care about indexed keys you can fetch grouped values:
what gives you
Lists<List<E>>view which contents can be easily copied toArrayListor just used as is, as you wanted in first place. Also note thatindexed.get(key)isImmutableList.EDIT 2: As Petr Gladkikh mentions in comment below, if
Collection<List<E>>is enough, above example could be simpler: