You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用Java 8 Stream将相邻线段列表分组?

用Java 8 Stream将相邻线段分组

我有一个由LineDetailsTO对象(包含start和end属性)组成的列表,示例输入如下:

[[P1,P2],[P2,P3],[P10,P11],[P11,P12],[P12,P13]]

需要把前一条线段的end与后一条的start相等的相邻线段归为同一子列表,最终得到:

[[[P1,P2],[P2,P3]],[[P10,P11],[P11,P12],[P12,P13]]]

我试过collect、reduce和groupBy方法但没成功,现在有一段可读性较差的实现代码,想知道怎么用Java 8 Stream更优雅地完成这个分组功能。

现有实现代码:

private static List<List<LineDetailsTO>> groupOverlappingMultipartLines(List<LineDetailsTO> overlappingMultipartLines){
    List<List<LineDetailsTO>> grouped = overlappingMultipartLines.stream()
            .collect(Collector.of(ArrayList::new, (groupedLines, currentLine) -> {
                if(groupedLines.isEmpty()) {
                    groupedLines.add(new ArrayList<>(Arrays.asList(currentLine)));
                } else {
                    List<LineDetailsTO> lastGroup = groupedLines.get(groupedLines.size() - 1);
                    LineDetailsTO lastLine = lastGroup.get(lastGroup.size() - 1);
                    if(lastLine.getEnd().equals(currentLine.getStart())){
                        lastGroup.add(currentLine);
                    } else {
                        groupedLines.add(new ArrayList<>(Arrays.asList(currentLine)));
                    }
                }
            }, (left, right) -> {left.addAll(right); return left;}));

    return grouped;
}

优化后的Stream实现

你的核心逻辑是正确的,只是可以通过语义化命名、拆分逻辑块、完善并行场景兼容来提升可读性和健壮性:

private static List<List<LineDetailsTO>> groupConnectedLines(List<LineDetailsTO> lines) {
    return lines.stream()
            .collect(Collector.of(
                    // 供应器:创建存放分组的容器
                    ArrayList::new,
                    // 累加器:处理每一条线段,判断加入现有分组还是新建分组
                    (groups, currentLine) -> {
                        if (groups.isEmpty()) {
                            groups.add(new ArrayList<>(Collections.singletonList(currentLine)));
                            return;
                        }
                        // 获取最后一个分组及组内最后一条线段
                        List<LineDetailsTO> lastGroup = groups.get(groups.size() - 1);
                        LineDetailsTO lastLine = lastGroup.get(lastGroup.size() - 1);
                        
                        if (lastLine.getEnd().equals(currentLine.getStart())) {
                            lastGroup.add(currentLine);
                        } else {
                            groups.add(new ArrayList<>(Collections.singletonList(currentLine)));
                        }
                    },
                    // 合并器:并行流场景下,合并两个分组列表(处理跨列表的连续线段)
                    (leftGroups, rightGroups) -> {
                        if (leftGroups.isEmpty()) return rightGroups;
                        if (rightGroups.isEmpty()) return leftGroups;
                        
                        // 检查左右列表是否可以首尾连接
                        List<LineDetailsTO> leftLastGroup = leftGroups.get(leftGroups.size() - 1);
                        LineDetailsTO leftLastLine = leftLastGroup.get(leftLastGroup.size() - 1);
                        List<LineDetailsTO> rightFirstGroup = rightGroups.get(0);
                        LineDetailsTO rightFirstLine = rightFirstGroup.get(0);
                        
                        if (leftLastLine.getEnd().equals(rightFirstLine.getStart())) {
                            leftLastGroup.addAll(rightFirstGroup);
                            rightGroups.remove(0);
                        }
                        leftGroups.addAll(rightGroups);
                        return leftGroups;
                    }
            ));
}

优化说明

  1. 语义化命名:把groupedLines改为groups,让变量作用更直观
  2. 替换工具方法:用Collections.singletonList替代Arrays.asList,更贴合“创建单元素列表”的语义,避免Arrays.asList的固定大小列表特性带来的潜在问题
  3. 完善并行流支持:原合并器只是简单拼接列表,优化后会检查左右分组列表的首尾线段是否连续,确保并行流场景下结果正确
  4. 逻辑拆分:通过空行和注释分割不同逻辑块,降低阅读成本

如果追求极致的可读性,也可以把“判断是否连续”的逻辑抽成单独方法,比如:

private static boolean isContinuous(LineDetailsTO prev, LineDetailsTO curr) {
    return prev.getEnd().equals(curr.getStart());
}

然后在累加器和合并器中调用这个方法,进一步简化代码。

内容的提问来源于stack exchange,提问作者Susitha Ravinda Senarath

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 14:25:16