【问题标题】:Counting the amount of object elements in one ArrayList occur in another ArrayList计算一个 ArrayList 中对象元素的数量发生在另一个 ArrayList 中
【发布时间】:2021-12-03 09:40:27
【问题描述】:

我有两个 ArrayLists 保存来自 pcap 文件的 TCP Flow 对象。一个列表是一个参考列表,其中包含找到的每个唯一数据包(没有双精度,只有找到的每个唯一数据包)。另一个列表是 Flow 对象的列表,这些对象的流程在我的程序中标记为已完成。

我的目标:使用参考列表,计算数据包出现在已完成流列表中的次数或频率。

TCP Flow Object定义如下:

public class Flow {
    String destIp;
    String sourceIp;
    String destPort;
    String srcPort;
    double arrivalTime;
    int completed;
}

可以使用destIp, sourceIp, destPort,srcPort 来识别每个TCP 流对象。

我之前发现我可以在 Collections 中使用频率方法,但我必须使用 4 个不同的元组来识别一行,而不仅仅是一个。我最初的计划是创建一个嵌套的 for 循环,从引用列表中检查一个数据包,然后检查已完成流列表中的每个数据包,例如:

for(Flow referenceList : refList) {
    for(Flow compList : cList) {
        if tuples match the one in cList add to count
    }
}

是否有更简单或更有效的方法来实现这一点?

【问题讨论】:

    标签: java pcap


    【解决方案1】:

    您可以使用Map 来处理O(n) 时间并将中间计数保存到其中。无需使用for 两次。

    public static class Flow {
    
        String destIp;
        String sourceIp;
        String destPort;
        String srcPort;
        double arrivalTime;
        int completed;
    
    }
    
    public static void main(String... args) {
        Function<Flow, String> getKey = flow ->
                String.format("%s|%s|%s|%s",
                        flow.sourceIp, flow.srcPort, flow.destIp, flow.destPort);
        List<Flow> refList = List.of();
        List<Flow> cList = List.of();
        Map<String, Long> histogram = histogram(refList, cList, getKey);
    }
    
    public static Map<String, Long> histogram(List<Flow> refList,
            List<Flow> cList, Function<Flow, String> getKey) {
        Map<String, Long> map =
                refList.stream()
                       .map(getKey)
                       .collect(Collectors.groupingBy(Function.identity(),
                               Collectors.counting()));
        
        Map<String, Long> res = new HashMap<>();
    
        cList.stream()
             .map(getKey)
             .filter(map::containsKey)
             .forEach(key -> res.put(key, map.get(key) + 1));
    
        return map;
    }
    

    【讨论】:

      【解决方案2】:

      它将花费的时间是N*M,其中 N 和 M 是这两个列表的大小。这变得昂贵,快速。 10k 条目中的每一个都有两个列表,这将开始非常非常长。

      假设这些列表并不小,那么您的数据类型就会混乱。如果其中一个是一个集合,那么这只是O(M),就像这样,那么它只需要大约 10k 步,好多了。您只制作一次并且所有内容都是独一无二的,听起来应该是一套。

      无论你走到这里,你必须在这个 Flow 类上有一个实际的 hashCode()equals() 方法。您可以在网上搜索有关如何编写它们的教程,或让 IDE 为您制作它们,或使用 Project Lombok 为您制作它们。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-12-12
        • 2020-07-21
        • 2013-05-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多