InetSocketAddress的Java Comparator

时间:2011-07-11 00:45:18

标签: java comparator treeset

我需要为ComparatorInetSocketAddress,以便我可以在TreeSet中使用此类。它们需要通过地址和端口进行比较。

代码看起来像这样,但问题是我不知道如何比较地址和端口<( - 1),>(1),=(0)

TreeSet<InetSocketAddress> _tree = new TreeSet<InetSocketAddress> 
    (new Comparator<InetSocketAddress>() {

    public int compare(InetSocketAddress o1, InetSocketAddress o2) {

        ///?????
        return 0;
    }
});

编辑......实际问题。如何比较InetSocketAddress。

5 个答案:

答案 0 :(得分:4)

使用InetSocketAddress#getHostName比较的代码不正确,因为当解析主机名时,它可以为null。看一下构造函数:

public InetSocketAddress(String hostname, int port) {
if (port < 0 || port > 0xFFFF) {
    throw new IllegalArgumentException("port out of range:" + port);
}
if (hostname == null) {
    throw new IllegalArgumentException("hostname can't be null");
}
try {
    addr = InetAddress.getByName(hostname);
} catch(UnknownHostException e) {
    this.hostname = hostname;
    addr = null;
}
this.port = port;
}

仅使用IP的代码也是错误的 - 主机名可能无法解析。这应该非常有效:

Integer getIp(InetSocketAddress addr) {
    byte[] a = addr.getAddress().getAddress();
    return ((a[0] & 0xff) << 24) | ((a[1] & 0xff) << 16) | ((a[2] & 0xff) << 8) | (a[3] & 0xff);
}

public int compare(InetSocketAddress o1, InetSocketAddress o2) {
    //TODO deal with nulls
    if (o1 == o2) {
        return 0;
    } else if(o1.isUnresolved() || o2.isUnresolved()){
        return o1.toString().compareTo(o2.toString());
    } else {
        int compare = getIp(o1).compareTo(getIp(o2));
        if (compare == 0) {
            compare = Integer.valueOf(o1.getPort()).compareTo(o2.getPort());
        }
        return compare;
    }
}

答案 1 :(得分:1)

排序需要

&lt;( - 1),&gt;(1),=(0) 我想你可以假设订购 - 例如:

public int compare(InetSocketAddress o1, InetSocketAddress o2) {
    //TODO deal with nulls
    if(o1 == o2){
        return 0;
    } else {
        return o1.toString().compareTo(o2.toString());
    }
}

这不是很有效,但它说明了这个想法。比较IP(可用时,已解决)可以更快。

答案 2 :(得分:1)

根据您是否需要特定订单或某种解决方案,这可能是正确的:

class ISC implements Comparator<InetSocketAddress>
{

@Override
    public int compare(InetSocketAddress o1, InetSocketAddress o2)
    {
        return o1.toString().compareTo(o2.toString());
    }
}

答案 3 :(得分:1)

尝试使用CompareToBuilder,然后传递getAddress().getHostAddress()getPort()

答案 4 :(得分:1)

你只需要选择一个约定。

e.g。

  1. 选择任意订购方案 用于IP地址。它只需要始终如一地应用。

    显然是点 符号表示一种自然的方式 这样做,所以你可以分解,例如127.0.0.1进入{127,0,0,1}和 比较它与另一个例如{84,23,10,2}要明确。

    另一种选择是将地址部分转换为长数字,然后只比较这些数字。这是基本的散列。

  2. 选择任意订购方案 对于端口号。似乎是明智的 只需使用数字语义和 例如将55号港口视为低于港口 999(虽然就IP协议而言 关注,这样的语义观点是 毫无意义。)

  3. 伪码:

    compare (addr1, addr2)
       if addr1.host > addr2.host return 1;
       else if addr1.host < addr2.host return -1;
    
       if addr1.port > addr2.port return 1;
       else if addr1.port < addr2.port return -1;
    
       return 0;