Search code examples
javacomparatortreeset

Java Comparator for InetSocketAddress


I need to write Comparator for InetSocketAddress so I can use this class in a TreeSet. They need to be comparable by address and port.

The code would look something like this, but the problem is I don't know how to compare addresses and ports by <(-1),>(1),=(0)

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

    public int compare(InetSocketAddress o1, InetSocketAddress o2) {

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

Edit... the actual question. How to compare InetSocketAddress.


Solution

  • Codes with InetSocketAddress#getHostName comparation is incorrect because when hostname is resolved it can be null. Look at constructor:

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

    The code wchich uses only IP is incorrect too - hostname can be unresolved. This should be quite efficient:

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