具有 InetSocketAddress#getHostName 比较的代码不正确,因为解析主机名时它可能为空。看构造函数:
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;
}
wchich 仅使用 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;
}
}