将列表的元素分组为子列表(也许通过使用番石榴)
我想对列表的元素进行分组。我目前正在这样做:
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);
}
有没有更好的方法来做到这一点,最好是使用番石榴?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
当然这是可能的,而且使用 Guava 更容易:) 使用
Multimaps.index(Iterable, Function)
:如果给出具体用途案件在行动中展示它会更容易。
文档示例:
prints
在您的情况下,如果 GroupFunction 定义为:
那么它将转换为:
这是 Guava 示例中使用的可能的
stringLengthFunction
实现。最后,在 Java 8 中,整个代码片段可能会更简单,因为ambas和方法引用足够简洁,可以内联:
对于纯 Java 8(无 Guava)示例,使用
Collector.groupingBy
参见<一href="https://stackoverflow.com/a/25953796/708434">Jeffrey Bosboom 的答案,尽管该方法有一些差异:ImmutableListMultimap
而是返回带有Collection
值的Map
,编辑:如果您不关心索引键,您可以获取分组值:
什么让您
Lists
查看可以轻松复制到哪些内容>
ArrayList
或按原样使用,正如您首先想要的那样。另请注意,indexed.get(key)
是ImmutableList
。编辑2:正如Petr Gladkikh提到的在下面的评论中,如果
Collection
就足够了,上面的例子可以更简单:>
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
stringLengthFunction
implementation 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.groupingBy
see Jeffrey Bosboom's answer, although there are few differences in that approach:ImmutableListMultimap
but ratherMap
withCollection
values,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 toArrayList
or 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:Java 8 流库中的
Collector.groupingBy
提供与 Guava 的Multimaps.index
相同的功能。这是 Xaerxess 的答案中的示例,重写为使用 Java 8 流:如果
您想将值与除了创建列表之外,以其他方式使用相同的键,您可以使用采用另一个收集器的
groupingBy
重载。此示例使用分隔符连接字符串:This will print
如果您有一个很大的列表或者您的分组函数很昂贵,您可以使用
parallelStream
和并发收集器进行并行。这可能会打印(顺序不再确定)
Collector.groupingBy
from the Java 8 streams library provides the same functionality as Guava'sMultimaps.index
. Here's the example in Xaerxess's answer, rewritten to use Java 8 streams:This will print
If you want to combine the values with the same key in some other way than creating a list, you can use the overload of
groupingBy
that takes another collector. This example concatenates the strings with a delimiter:This will print
If you have a large list or your grouping function is expensive, you can go parallel using
parallelStream
and a concurrent collector.This may print (the order is no longer deterministic)
最简单的方法是使用: Lambdaj 分组功能
上面的示例可以被重写:
The easiest and simplest way would be using: Lambdaj grouping feature
The above example can be re-written:
使用 Java 8、Guava 和一些辅助函数,您可以使用自定义比较器
示例实现分组
With Java 8, Guava and few helper functions you can implement grouping with custom Comparator
Example