【问题标题】:Using partitions of List/Collections dynamically in Java?在 Java 中动态使用列表/集合的分区?
【发布时间】:2016-11-22 13:17:30
【问题描述】:

我有一个用例,从总共 n 个元素中提取 x 个元素。目前我正在使用这样的谷歌番石榴列表:

List<String> dataList; 

List< List<String> > smallerLists = Lists.partition(dataList, maxRecordsInABatch); 

for ( smallerList : smallerLists ) {
    doSomething(data);
}

有没有更好的方法来做到这一点,我可以避免制作更小的列表,并在运行时从 n 大小的列表中选择 x 大小的列表。

我也在探索 Java 8 Streams 和 Lambda 表达式,但找不到适合的东西。

【问题讨论】:

  • 如果您查看Lists.partition() 的来源,您会发现您会在通过的列表中获得Partition,它调用subList()。如果调用的内置列表将创建对底层列表进行操作的小对象,因此实际上您的代码不应生成任何新列表。
  • Lists.partition() 让我觉得这是一个非常好的方法;如果没有更多关于您认为“更好”的信息,我无法说出如何击败它。列表中的所有项目都没有重复,实际上也没有对象指针重复 - 根据 javadocs,较小的列表是较大列表的视图。我能猜到的唯一两个可能的改进是您想要修改较小的列表而不更改较大的列表(soln:克隆子列表),或者您想做某种云工作。这些都成立吗?
  • @Thomas @Paul Brinkley 我唯一担心的是数据冗余。我在想Lists.partition() 使用原始列表中的数据副本创建新的较小列表。如果不是这种情况,实际上我正在使用相同的基础列表,那么我的方法很好。
  • 事实上,即使你得到新的列表,它们仍然会引用相同的数据,即不会复制列表中的元素,只会复制对它们的引用(大约 8 个字节每个参考)。

标签: java list lambda java-8 partitioning


【解决方案1】:

有一个小技巧可以用于 java-8 中的列表分区。 首先,您按分区数对拆分进行分组,然后创建一个包含分组值的新列表。像这样的:

List<Integer> intList = Lists.newArrayList(1, 2, 3, 4, 5, 6, 7, 8);
Map<Integer, List<Integer>> groups = intList.stream().collect(Collectors.groupingBy(s -> (s - 1) / 3));
System.out.println(groups);
List<List<Integer>> subSets = new ArrayList<List<Integer>>(groups.values());
System.out.println(subSets);

【讨论】:

    【解决方案2】:

    您可以使用partioningBy 收集器。 如以下链接所述: https://www.javacodegeeks.com/2015/11/java-8-streams-api-grouping-partitioning-stream.html

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-12-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-12
      • 2016-04-04
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多