Компаратор Java для InetSocketAddress - PullRequest
3 голосов
/ 11 июля 2011

Мне нужно написать Comparator для InetSocketAddress, чтобы я мог использовать этот класс в TreeSet.Они должны быть сопоставимы по адресу и порту.

Код будет выглядеть примерно так, но проблема в том, что я не знаю, как сравнить адреса и порты по <(- 1),> (1), = (0)

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

    public int compare(InetSocketAddress o1, InetSocketAddress o2) {

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

Редактировать ... актуальный вопрос.Как сравнить InetSocketAddress.

Ответы [ 5 ]

4 голосов
/ 11 июля 2011

Коды с 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;
}

Код, который использует только 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 голос
/ 11 июля 2011

Вам просто нужно выбрать соглашение.

, например

  1. выберите произвольную схему заказа для IP-адресов. Это просто необходимо последовательно применять.

    Очевидно, точка нотация предлагает естественный способ делая это, так что вы можете сломать, например, 127.0.0.1 в {127, 0, 0, 1} и сравните это с другим, например {84, 23, 10, 2}, чтобы быть явным.

    Другой вариант - преобразовать адресную часть в длинное число и просто сравнить эти числа. Это базовое хеширование.

  2. выберите произвольную схему заказа для номеров портов. Кажется разумным просто используйте числовую семантику и например обрабатывать порт 55 как порт 999 (хотя, насколько IP-протокол обеспокоен, такой семантический взгляд бессмысленны.)

псевдо-код:

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;
1 голос
/ 11 июля 2011

В зависимости от того, нужен ли вам конкретный заказ или какое-либо разрешение, это может быть правильным:

class ISC implements Comparator<InetSocketAddress>
{

@Override
    public int compare(InetSocketAddress o1, InetSocketAddress o2)
    {
        return o1.toString().compareTo(o2.toString());
    }
}
1 голос
/ 11 июля 2011

Попробуйте использовать CompareToBuilder и введите getAddress().getHostAddress() и getPort().

1 голос
/ 11 июля 2011

<(- 1),> (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 (когда оно доступно, разрешено) может быть быстрее.

...