Учитывая список IP-адресов, как вы находите min, max?
в Java у меня есть arrayList ip-адреса. как мне найти min и Max ?
я использовал коллекцию.min (), но он не работает, учитывая такой случай, как :
192.168.0.1 <--min
192.168.0.250
192.168.0.9 <--max
как мне вернуть
192.168.0.1 <--min
192.168.0.250 <--max
вместо?
ArrayList извлекается из базы данных. Мне нужно будет сделать эту операцию за тик (каждый тик находится на интервале 5 секунд). Число IP-адресов достигнет максимума, вероятно, 300.
5 ответов
преобразуйте IP-адрес в длинное целое число, затем отсортируйте его. 192.168.0.1
можно преобразовать в целое число с помощью двоичной арифметики / операторов:
( 192 << 24 ) + ( 168 << 16 ) + ( 0 << 8 ) + ( 1 << 0 )
и так далее. Прочитайте комментарии ниже об использовании правильного типа данных.
вы храните IP-адреса String
экземпляров? Это, вероятно, так, потому что String
сортируются лексикографически, что означает "10" < "2"
.
если вы хотите отсортировать их численно, есть несколько способов:
- вместо того, чтобы положить их в
List<String>
, положил их вList<Integer>
- или даже
SortedSet<Integer>
- или даже
- сохранить
List<String>
, но предоставьте пользовательский компаратор, который преобразуетString
to числовое значение для сравнения- может быть не самым эффективным, но работает без серьезных изменений в существующей инфраструктуре
- хотя, возможно, серьезные изменения-неплохая идея для начала...
- может быть не самым эффективным, но работает без серьезных изменений в существующей инфраструктуре
вот пример, который объединяет немного обоих в один:
import java.util.*;
public class IPSorter {
static Long toNumeric(String ip) {
Scanner sc = new Scanner(ip).useDelimiter("\.");
return
(sc.nextLong() << 24) +
(sc.nextLong() << 16) +
(sc.nextLong() << 8) +
(sc.nextLong());
}
public static void main(String[] args) {
Comparator<String> ipComparator = new Comparator<String>() {
@Override public int compare(String ip1, String ip2) {
return toNumeric(ip1).compareTo(toNumeric(ip2));
}
};
SortedSet<String> ips = new TreeSet<String>(ipComparator);
ips.addAll(Arrays.asList(
"192.168.0.1", "192.168.0.250", "192.168.0.9", "9.9.9.9"
));
System.out.println(ips);
// "[9.9.9.9, 192.168.0.1, 192.168.0.9, 192.168.0.250]"
}
}
API-интерфейс ссылки
ссыль Java-IP-адрес для Integer и обратно
public static String intToIp(int i) {
return ((i >> 24 ) & 0xFF) + "." +
((i >> 16 ) & 0xFF) + "." +
((i >> 8 ) & 0xFF) + "." +
( i & 0xFF);
}
public static Long ipToInt(String addr) {
String[] addrArray = addr.split("\.");
long num = 0;
for (int i=0;i<addrArray.length;i++) {
int power = 3-i;
num += ((Integer.parseInt(addrArray[i])%256 * Math.pow(256,power)));
}
return num;
}
извлекая из базы данных строку Ip-адреса, я преобразовал все в ArrayList, а затем применил коллекцию.минута() Затем я преобразую long в int, а затем обратно в String. Для получения отсортированной строки ip-адресов.
спасибо
Если вы рассматриваете IP-адреса как целое число (long), вы можете сортировать по нему. Напишите пользовательский компаратор, который может разделить IP-адрес на массив ints, а затем создать общее значение int, выполнив следующие действия.
//Split and convert the address into an array of ints...
addressIntValue = address[0] * 256 * 256 * 256
addressIntValue += address[1] * 256 * 256
addressIntValue += address[2] * 256
addressIntValue += address[3]
затем вы можете сортировать по "addressIntValue".
если вы не хотите анализировать IP вручную, вы можете использовать InetAddress
класс
InetAddress ia1 = InetAddress.getByName("192.168.0.9");
InetAddress ia2 = InetAddress.getByName("192.168.0.234");
System.out.println(ia1.hashCode() < ia2.hashCode());
Я использую hashCode()
метод, потому что он возвращает адрес как номер для IPv4. Вы также можете сравнить массивы, возвращаемые InetAddress.getAddress()
редактировать используя hashCode()
является недокументированной функцией, и могут возникнуть проблемы, если у вас есть адреса ipv6 и ipv4. Поэтому лучше всего сравнивать массивы байтов или конвертировать их в число вручную.