给出一个IP地址列表,你如何找到min,max?

时间:2010-05-11 08:01:04

标签: java collections ip-address

在Java中,我有一个ip地址的arrayList。我如何找到最小值和最大值?

我已经使用了Collection.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 个答案:

答案 0 :(得分:13)

将IP地址转换为长整数,然后对其进行排序。 192.168.0.1可以使用二进制算术运算符转换为整数:

( 192 << 24 ) + ( 168 << 16 ) + ( 0 << 8 ) + ( 1 << 0 )

等等。请阅读以下有关使用正确数据类型的注释。

答案 1 :(得分:7)

您是否将IP地址存储为String个实例?这可能是这种情况,因为String按字典顺序排序,意味着"10" < "2"

如果你想用数字排序,有几种方法:

  • 而不是将它们放入List<String>,而是将它们放入List<Integer>
    • 或者甚至是SortedSet<Integer>
  • 保留List<String>,但提供自定义比较器,将String转换为数值进行比较
    • 可能效率不高,但无需对现有基础架构进行重大更改即可运行
      • 虽然也许重大改变并不是一个坏主意......

这是一个将两者结合成一个的例子:

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链接

答案 2 :(得分:2)

如果将IP地址视为整数(长整数),则可以对其进行排序。编写一个自定义比较器,可以将IP地址拆分为一个int数组,然后通过执行以下操作创建一个total 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”进行排序。

答案 3 :(得分:2)

参考Java – IP Address to Integer and back

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,然后应用Collection.min() 然后我将long转换回int然后再转换回String。获取已排序的IP地址字符串。

由于

答案 4 :(得分:1)

如果您不想手动解析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地址,则可能会出现问题。因此,最好比较字节数组或手动将它们转换为数字。