gpt4 book ai didi

java - 为双向流实现类似的接口(interface)

转载 作者:行者123 更新时间:2023-12-02 08:30:35 25 4
gpt4 key购买 nike

这段代码应该将两个方向的流视为一个流。例如:

srcAddr,dstAddr,srcPort,dstPort
192.168.1.65, 217.174.16.1, 123456,80

应该与

相同
217.174.16.1, 192.168.1.65,80,123456

另一个例子:

192.168.1.65, 217.174.16.1, 12345, 80, TCP
217.174.16.1, 192.168.1.65, 80, 12345, TCP
192.168.1.65, 217.174.16.1, 12345, 80, TCP
217.174.16.1, 192.168.1.65, 80, 12345, TCP

我想保持这样:

Flow 1: key---> value (keeps statistics about each packet, like length and timeArrival)

[192.168.1.65, 217.174.16.1, 12345, 80] ----> [(outgoing, 1,2)(incoming,3,4)()()...]

192.168.1.65、69.100.70.80、98521、80
69.100.70.80、192.168.1.65、80、98521
192.168.1.65、69.100.70.80、98521、80
69.100.70.80、192.168.1.65、80、98521
192.168.1.65、69.100.70.80、98521、80
69.100.70.80、192.168.1.65、80、98521

流程 2:[192.168.1.65, 69.100.70.80, 98521, 80] --> [(传出, 1,2)(传入,3,4)()()...]

我应该如何改变它才能得到结果?[我使用 hashMap,此类 Flows 是我的 key ]

 package myclassifier;
public class Flows implements Comparable<Flows> {

String srcAddr = "", dstAddr = "", protocol = "";
int srcPort = 0, dstPort = 0;

public Flows(String sIP, String dIP, int sPort, int dPort){
this.srcAddr = sIP;
this.dstAddr = dIP;
this.srcPort = sPort;
this.dstPort = dPort;
//this.protocol = protocol;

}
public Flows(){

}

public int compareTo(Flows other) {
int res = 1;
if(this.equals(other)){
return res=0;
}else
return 1;
}



@Override
public int hashCode() {

final int prime = 31;
int result = 1;
result = prime * result + ((dstAddr == null) ? 0 : dstAddr.hashCode());
result = prime * result + dstPort;
result = prime * result + ((srcAddr == null) ? 0 : srcAddr.hashCode());
result = prime * result + srcPort;
return result;

}

@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;

if (getClass() != obj.getClass())
return false;

Flows other = (Flows) obj;

if (dstAddr == null) {
if (other.dstAddr != null)
return false;
} else if (!dstAddr.equals(other.dstAddr))
return false;
if (dstPort != other.dstPort)
return false;
if (srcAddr == null) {
if (other.srcAddr != null)
return false;
} else if (!srcAddr.equals(other.srcAddr))
return false;
if (srcPort != other.srcPort)
return false;
return true;

}

@Override
public String toString() {
return String.format("[%s, %s, %s, %s, %s]", srcAddr, dstAddr, srcPort, dstPort, protocol);
}


}

最佳答案

可能最简洁的方法是定义这些方法:

  • Flows reverse()返回相反方向 Flows给定的Flows
  • Flows canon()它返回 Flows 的规范化形式
    • 您可以定义例如一个Flows是佳能如果 srcAddr.compareTo(dstAddr) <= 0
    • 否则,其reverse()根据定义是佳能

然后,对于非定向比较,您可以简单地比较两个流的规范形式。拥有这些方法使得其余的逻辑非常干净和可读(参见下面的代码)。

<小时/>

Comparator , Comparable ,并与 equals 保持一致

使用reverse()上面的概念,如果你想要f.equals(f.reverse())总是,那么也许一开始就不应该有任何方向性的概念。如果是这种情况,那么规范化是最好的方法。

如果f一般不是equals(f.reverse()) ,但您可能想要 ff.reverse()与 0 比较,则 Comparable 不应使用,因为这样做会强加与 equals 不一致的自然顺序。

来自文档:

The natural ordering for a class C is said to be consistent with equals if and only if e1.compareTo(e2) == 0 has the same boolean value as e1.equals(e2) for every e1 and e2 of class C.

It is strongly recommended (though not required) that natural orderings be consistent with equals.

也就是说,不要在 Comparable 中强加自然排序。这与 equals 不一致,您应该提供一个非定向 Comparator 相反。

打个比方,将此情况与 String 进行比较,它提供 Comparator<String> CASE_INSENSITIVE_ORDER ,它允许两个不是 equals 的字符串与 0 进行比较,不区分大小写。

所以在这里你可以写一个Comparator<Flows>允许两个 Flows不是equals通过方向不敏感与 0 进行比较。

另请参阅

相关问题

<小时/>

实现示例

这是 Edge 的示例实现具有 from 的类和to ,具有与 equals 一致的定向自然排序,它还提供了非定向 Comparator .

然后用 3 种 Set 进行测试:

  • 一个HashSet ,测试equalshashCode
  • 一个TreeSet ,测试自然排序
  • 一个TreeSet与定制Comparator ,测试非方向性

实现简洁明了,应该具有指导意义。

import java.util.*;

class Edge implements Comparable<Edge> {
final String from, to;

public Edge(String from, String to) {
this.from = from;
this.to = to;
}
@Override public String toString() {
return String.format("%s->%s", from, to);
}
public Edge reverse() {
return new Edge(to, from);
}
public Edge canon() {
return (from.compareTo(to) <= 0) ? this : this.reverse();
}
@Override public int hashCode() {
return Arrays.hashCode(new Object[] {
from, to
});
}
@Override public boolean equals(Object o) {
return (o instanceof Edge) && (this.compareTo((Edge) o) == 0);
}
@Override public int compareTo(Edge other) {
int v;

v = from.compareTo(other.from);
if (v != 0) return v;

v = to.compareTo(other.to);
if (v != 0) return v;

return 0;
}
public static Comparator<Edge> NON_DIRECTIONAL =
new Comparator<Edge>() {
@Override public int compare(Edge e1, Edge e2) {
return e1.canon().compareTo(e2.canon());
}
};
}

public class Main {
public static void main(String[] args) {
testWith(new HashSet<Edge>());
testWith(new TreeSet<Edge>());
testWith(new TreeSet<Edge>(Edge.NON_DIRECTIONAL));
}
public static void testWith(Set<Edge> set) {
set.clear();
set.add(new Edge("A", "B"));
set.add(new Edge("C", "D"));
System.out.println(set.contains(new Edge("A", "B")));
System.out.println(set.contains(new Edge("B", "A")));
System.out.println(set.contains(new Edge("X", "Y")));
System.out.println(set);
set.add(new Edge("B", "A"));
set.add(new Edge("Z", "A"));
System.out.println(set);
System.out.println();
}
}

输出如下 ( as seen on ideone.com ),带注释:

// HashSet
// add(A->B), add(C->D)
true // has A->B?
false // has B->A?
false // has X->Y?
[C->D, A->B]
// add(B->A), add(Z->A)
[B->A, C->D, Z->A, A->B]

// TreeSet, natural ordering (directional)
// add(A->B), add(C->D)
true // has A->B?
false // has B->A?
false // has X->Y
[A->B, C->D]
// add(B->A), add(Z->A)
[A->B, B->A, C->D, Z->A]

// TreeSet, custom comparator (non-directional)
// add(A->B), add(C->D)
true // has A->B?
true // has B->A?
false // has X->Y?
[A->B, C->D]
// add(B->A), add(Z->A)
[A->B, Z->A, C->D]

请注意,在非定向 TreeSet 中, Z->A被规范化为A->Z ,这就是为什么它出现在 C->D 之前按这个顺序。同样,B->A被规范化为A->B ,它已经在集合中,这解释了为什么只有 3 Edge那里。

要点

  • Edge是不可变的
  • Arrays.hashCode(Object[]) 是为了方便而使用的;无需编写所有公式
  • 如果自然排序与 equals 一致,您可以使用compareTo == 0equals
  • 使用多步骤 return compareTo中的逻辑为了简洁和清晰
  • reverse()canon()大大简化了非定向比较
    • 简单地按照自然顺序比较它们的规范化形式

另请参阅

  • Effective Java 第二版
    • 第8条:覆盖时遵守总契约(Contract)equals
    • 第 9 项:始终覆盖 hashCode当您覆盖equals
    • 第 10 项:始终覆盖 toString
    • 第 12 项:考虑实现 Comparable
    • 第 15 项:最小化可变性
    • 第 36 项:始终使用 @Override注释
    • 第 47 项:了解和使用库

关于java - 为双向流实现类似的接口(interface),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3501108/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com