Java 实现双向流的可比较接口 这段代码应该考虑两个方向的流作为一个流。 例如: srcAddr,dstAddr,srcPort,dstPort 192.168.1.65, 217.174.16.1, 123456,80

Java 实现双向流的可比较接口 这段代码应该考虑两个方向的流作为一个流。 例如: srcAddr,dstAddr,srcPort,dstPort 192.168.1.65, 217.174.16.1, 123456,80,java,network-programming,overriding,compare,comparable,Java,Network Programming,Overriding,Compare,Comparable,应与相同 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---&

应与相同

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.8098521,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.80192.168.1.658098521

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

我应该如何更改它以获得结果? [我使用hashMap,这类流是我的密钥]

 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);
}


}
package-myclassifier;
公共类流实现了可比性{
字符串srcadr=“”,dstAddr=“”,protocol=“”;
int srcPort=0,dstPort=0;
公共流(串sIP、串dIP、int sPort、int dPort){
this.srcadr=sIP;
此.dstAddr=倾角;
this.srcPort=sPort;
this.dsport=dPort;
//本协议=协议;
}
公共流量(){
}
公共int比较(其他流量){
int res=1;
如果(这个等于(其他)){
返回res=0;
}否则
返回1;
}
@凌驾
公共int hashCode(){
最终整数素数=31;
int结果=1;
result=prime*result+((dstAddr==null)?0:dstAddr.hashCode();
结果=素数*结果+数据端口;
result=prime*result+((srcadr==null)?0:srcadr.hashCode();
结果=prime*result+srcPort;
返回结果;
}
@凌驾
公共布尔等于(对象obj){
if(this==obj)
返回true;
if(obj==null)
返回false;
如果(getClass()!=obj.getClass())
返回false;
其他流量=(流量)obj;
if(dstAddr==null){
if(other.dstAddr!=null)
返回false;
}如果(!dstAddr.equals(other.dstAddr))
返回false;
if(dstPort!=其他.dstPort)
返回false;
if(srcadr==null){
if(other.srcadr!=null)
返回false;
}else如果(!srcadr.equals(other.srcadr))
返回false;
if(srcPort!=其他.srcPort)
返回false;
返回true;
}
@凌驾
公共字符串toString(){
返回字符串.format(“[%s,%s,%s,%s,%s]”,srcadr,dstAddr,srcPort,dstPort,protocol);
}
}

最干净的方法可能是定义以下方法:

  • Flows reverse()
    返回给定
    流的反向
  • Flows canon()
    返回
    Flows的规范化形式
    
    • 例如,如果
      srcadr.compareTo(dstAddr)a
      被规范化为
      a->Z
      ,则可以定义a
      为佳能,这就是它按此顺序出现在
      C->D
      之前的原因。类似地,
      B->A
      被规范化为
      A->B
      ,它已经在集合中,这解释了为什么那里只有3个
      Edge

      要点
      • Edge
        是不可变的
      • 用于方便;不需要对所有公式进行编码
      • 如果自然顺序与
        equals
        一致,则可以在
        equals
        中使用
        compareTo==0
      • 使用
        compareTo
        中的多步骤
        返回
        逻辑,以简洁明了
      • 拥有
        reverse()
        canon()
        大大简化了非方向性比较
        • 简单地比较它们的自然顺序中的规范化形式
      另见
      • 有效Java第二版
        • 第8项:当覆盖
          等于
        • 第9项:当覆盖
          等于时,始终覆盖
          hashCode
        • 第10项:始终覆盖
          toString
        • 项目12:考虑实施<代码>可比< /代码>
        • 项目15:尽量减少可变性
        • 第36项:始终使用
          @Override
          注释
        • 项目47:了解和使用图书馆

      关键是正确实现equals方法。在equals方法中,当目标地址不匹配时,返回false。这是您需要添加额外逻辑来检查相等性的地方,因为您希望具有双向相等性。相等的第一步应该是检查源、目标和端口的相等性。第二个过程应该是源和目标的反向相等。您还需要对默认值进行特殊设置,例如在您的示例中,排除portno(80)默认值为true。

      我不知道这是否会对您有所帮助。但正如您所说,它在两个方向都有效

      import java.util.HashSet;
       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) {
      
          if(this.equals(other)){
              return 0;
          }else
              return 1;
      }
      
      
      
       @Override
      public int hashCode() {
          final int prime = 31;
          int result = 1;
          result = prime * result + ((dstAddr == null) ? 0 : dstAddr.hashCode())+((srcAddr == null) ? 0 : srcAddr.hashCode());
          result = prime * result + dstPort+srcPort;
          return result;
      
      }
      
      @Override
      public boolean equals(Object obj) {
         if (this == obj)
              return true;
      
         if(obj instanceof Flows)
         {
          Flows c=(Flows)obj;
          if(srcAddr.equals(c.dstAddr) && dstAddr.equals(c.srcAddr) &&srcPort==c.dstPort && dstPort==c.srcPort)
            return true;
      
          if(srcAddr.equals(c.srcAddr) && dstAddr.equals(c.dstAddr) && srcPort==c.srcPort && dstPort==c.dstPort)
              return true;
         }
          return false;
      
      }
      
       @Override
      public String toString() {
      return String.format("[%s, %s, %s, %s, %s]", srcAddr, dstAddr, srcPort, dstPort, protocol);
      }
      
      public static void main(String[] args) {
          Flows f1=new Flows("192.168.1.65","217.174.16.1", 123456,80);
          Flows f2=new Flows("217.174.16.1","192.168.1.65",80,123456);
      
          Flows f3=new Flows("192.168.1.66","217.174.16.1", 123456,80);
          Flows f4=new Flows("217.174.16.1","192.168.1.66",80, 123456);
          System.out.println(f1.hashCode()+ " "+f2.hashCode());
          HashSet<Flows> hh=new HashSet<Flows>();
          hh.add(f1);
          hh.add(f2);
          hh.add(f3);
          hh.add(f4);
          System.out.println(f1.compareTo(f2));
          System.out.println(hh);
      }
      }
      
      import java.util.HashSet;
      公共类流实现了可比性{
      字符串srcadr=“”,dstAddr=“”,protocol=“”;
      int srcPort=0,dstPort=0;
      公共流(串sIP、串dIP、int sPort、int dPort){
      this.srcadr=sIP;
      此.dstAddr=倾角;
      this.srcPort=sPort;
      this.dsport=dPort;
      //本协议=协议;
      }
      公共流量(){
      }
      公共int比较(其他流量){
      如果(这个等于(其他)){
      返回0;
      }否则
      返回1;
      }
      @凌驾
      公共int hashCode(){
      最终整数素数=31;
      int结果=1;
      result=prime*result+((dstAddr==null)?0:dstAddr.hashCode())+((srcAddr==null)?0:srcAddr.hashCode());
      结果=prime*result+dstPort+srcPort;
      返回结果;
      }
      @凌驾
      公共布尔等于(对象obj){
      if(this==obj)
      返回true;
      if(流程的obj实例)
      {
      流量c=(流量)obj;
      如果(srcadr.equals(c.dstAddr)&&dstAddr.equals(c.srcadr)&&srcPort==c.dstPort&&dstPort==c.srcPort)
      返回true;
      如果(srcadr.equals(c.srcadr)&&dstAddr.equals(c.dstAddr)&&srcPort==c.srcPort&&dstPort==c.dstPort)
      返回true;
      }
      返回false;
      }
      @凌驾
      公共字符串toString(){
      返回String.format(“[%s,
      
      // 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]
      
      import java.util.HashSet;
       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) {
      
          if(this.equals(other)){
              return 0;
          }else
              return 1;
      }
      
      
      
       @Override
      public int hashCode() {
          final int prime = 31;
          int result = 1;
          result = prime * result + ((dstAddr == null) ? 0 : dstAddr.hashCode())+((srcAddr == null) ? 0 : srcAddr.hashCode());
          result = prime * result + dstPort+srcPort;
          return result;
      
      }
      
      @Override
      public boolean equals(Object obj) {
         if (this == obj)
              return true;
      
         if(obj instanceof Flows)
         {
          Flows c=(Flows)obj;
          if(srcAddr.equals(c.dstAddr) && dstAddr.equals(c.srcAddr) &&srcPort==c.dstPort && dstPort==c.srcPort)
            return true;
      
          if(srcAddr.equals(c.srcAddr) && dstAddr.equals(c.dstAddr) && srcPort==c.srcPort && dstPort==c.dstPort)
              return true;
         }
          return false;
      
      }
      
       @Override
      public String toString() {
      return String.format("[%s, %s, %s, %s, %s]", srcAddr, dstAddr, srcPort, dstPort, protocol);
      }
      
      public static void main(String[] args) {
          Flows f1=new Flows("192.168.1.65","217.174.16.1", 123456,80);
          Flows f2=new Flows("217.174.16.1","192.168.1.65",80,123456);
      
          Flows f3=new Flows("192.168.1.66","217.174.16.1", 123456,80);
          Flows f4=new Flows("217.174.16.1","192.168.1.66",80, 123456);
          System.out.println(f1.hashCode()+ " "+f2.hashCode());
          HashSet<Flows> hh=new HashSet<Flows>();
          hh.add(f1);
          hh.add(f2);
          hh.add(f3);
          hh.add(f4);
          System.out.println(f1.compareTo(f2));
          System.out.println(hh);
      }
      }