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

如何用Java Streams实现同Log ID下重复Tag的检测逻辑?

使用Java Streams检测同一ID下重复Tag的实现方案

核心思路

要实现「同一ID下同一Tag重复则抛出异常」的逻辑,关键是先将每个Log对象拆分为**(ID, Tag)二元组**,再通过分组统计或重复检测来判断是否存在重复组合。

基础实现(分组统计)

首先定义Log类:

class Log {
    private String id;
    private List<String> tags;

    public Log(String id, List<String> tags) {
        this.id = id;
        this.tags = tags;
    }

    public String getId() { return id; }
    public List<String> getTags() { return tags; }
}

通过flatMap拆分Log为二元组,再用groupingBy统计每个(ID, Tag)组合的出现次数:

import java.util.List;
import java.util.Map;
import java.util.AbstractMap.SimpleEntry;
import java.util.stream.Collectors;

public class LogTagChecker {
    public static void checkForDuplicateTags(List<Log> logs) {
        // 拆分Log为(ID, Tag)二元组,分组统计次数
        Map<SimpleEntry<String, String>, Long> tagCountById = logs.stream()
                .flatMap(log -> log.getTags().stream()
                        .map(tag -> new SimpleEntry<>(log.getId(), tag)))
                .collect(Collectors.groupingBy(
                        entry -> entry,
                        Collectors.counting()));

        // 检测是否存在次数>1的组合
        if (tagCountById.values().stream().anyMatch(count -> count > 1)) {
            throw new IllegalStateException("存在同一ID下重复的Tag");
        }
    }

    public static void main(String[] args) {
        // 测试用例1:应抛出异常(log1的tag1重复)
        List<Log> duplicateLogs = List.of(
                new Log("log1", List.of("tag1", "tag2")),
                new Log("log1", List.of("tag1"))
        );
        checkForDuplicateTags(duplicateLogs);

        // 测试用例2:正常执行(无重复Tag)
        List<Log> validLogs = List.of(
                new Log("log1", List.of("tag1", "tag2")),
                new Log("log2", List.of("tag1"))
        );
        checkForDuplicateTags(validLogs);
    }
}

简化写法(Java 16+ Record)

用Java 16引入的record替代SimpleEntry,代码更清晰:

// 定义Record作为分组键
record IdTag(String id, String tag) {}

// 对应统计逻辑
Map<IdTag, Long> tagCountById = logs.stream()
        .flatMap(log -> log.getTags().stream()
                .map(tag -> new IdTag(log.getId(), tag)))
        .collect(Collectors.groupingBy(
                idTag -> idTag,
                Collectors.counting()));

高效优化版(无需全量统计)

如果只需要检测是否存在重复,不需要统计所有次数,可以用Set跟踪已出现的二元组,一旦发现重复立即终止流,减少不必要的计算:

import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.AbstractMap.SimpleEntry;

public class LogTagChecker {
    public static void checkForDuplicateTagsOptimized(List<Log> logs) {
        Set<SimpleEntry<String, String>> seen = new HashSet<>();
        boolean hasDuplicates = logs.stream()
                .flatMap(log -> log.getTags().stream()
                        .map(tag -> new SimpleEntry<>(log.getId(), tag)))
                .anyMatch(entry -> !seen.add(entry)); // add返回false说明已存在

        if (hasDuplicates) {
            throw new IllegalStateException("存在同一ID下重复的Tag");
        }
    }
}

关键步骤解释

  • flatMap:将每个Log的List<String> tags展开为多个独立的(ID, Tag)条目,解决了List类型无法直接作为分组键的问题。
  • 分组键选择:SimpleEntry或自定义record都重写了equals()和hashCode(),可以作为groupingBy的键来唯一标识「ID+Tag」组合。
  • 快速检测:anyMatch和Set.add()的组合能在找到第一个重复时立即停止遍历,性能优于全量统计。

内容的提问来源于stack exchange,提问作者user24498812

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 21:33:21