简体   繁体   English

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

[英]Given a list of IP address, how do you find min, max?

In Java, i have an arrayList of ip address. 在Java中,我有一个ip地址的arrayList。 how do i find the min and max ? 我如何找到最小值和最大值?

I have used the Collection.min() but it doesnt work given a case like : 我已经使用了Collection.min()但它不起作用给出如下情况:

192.168.0.1  <--min 
192.168.0.250
192.168.0.9  <--max

how do i return 我该如何回归

192.168.0.1  <--min
192.168.0.250 <--max

instead? 代替?


ArrayList is retrieve from the database. ArrayList是从数据库中检索的。 I would need to do this operation per tick (each tick is at 5 sec interval). 我需要每次滴答做这个操作(每个滴答间隔为5秒)。 The number of IP address would hit a max of probably 300. IP地址的数量最多可能达到300。

Convert the IP address into a long integer, then sort it. 将IP地址转换为长整数,然后对其进行排序。 192.168.0.1 can be converted to an integer using binary arithmetic/operators: 可以使用二进制算术/运算符将192.168.0.1转换为整数:

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

and so on. 等等。 Do read the comments below about using the correct data type. 请阅读以下有关使用正确数据类型的注释。

Are you storing the IP addresses as String instances? 您是否将IP地址存储为String实例? This is likely the case, because String are sorted lexicographically, meaning "10" < "2" . 这可能是这种情况,因为String按字典顺序排序,意味着"10" < "2"

If you want to sort them numerically, there are several ways: 如果要以数字方式对它们进行排序,有以下几种方法:

  • Instead of putting them into a List<String> , put them into a List<Integer> 而不是将它们放入List<String> ,而是将它们放入List<Integer>
    • or maybe even a SortedSet<Integer> 或者甚至是SortedSet<Integer>
  • Keep the List<String> , but provide a custom comparator that convert the String to numerical value for comparison 保留List<String> ,但提供自定义比较器,将String转换为数值以进行比较
    • may not be most efficient, but works without major changes to existing infrastructure 可能效率不高,但在没有对现有基础设施进行重大更改的情
      • although perhaps major changes isn't a bad idea to begin with... 虽然也许重大改变从一开始就不是一个坏主意......

Here's an example that combines a bit of both into one: 这是一个将两者结合成一个的例子:

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

If you treat the IP addresses as an integer (long), you can then sort on it. 如果将IP地址视为整数(长整数),则可以对其进行排序。 Write a custom comparer that can split the IP address into an array of ints, and then create a total int value by doing the following. 编写一个自定义比较器,可以将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]

You can then sort on "addressIntValue". 然后,您可以对“addressIntValue”进行排序。

Referring to Java – IP Address to Integer and back 参考Java - 整数和后面的IP地址

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

Retrieving from the database the Ip address String, I converted all to a ArrayList and then apply the Collection.min() Then I convert back the long to int and then back to String. 从数据库中检索Ip地址字符串,我将所有转换为ArrayList,然后应用Collection.min()然后我将long转换回int然后再转换回String。 To obtain a sorted String of ip addresses. 获取已排序的IP地址字符串。

Thanks 谢谢

In case you don't want to parse the IP by hand, you can use InetAddress class 如果您不想手动解析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());

I'm using the hashCode() method because it returns the address as a number for ipv4. 我正在使用hashCode()方法,因为它返回地址作为ipv4的数字。 You can also compare arrays returned by InetAddress.getAddress() 您还可以比较InetAddress.getAddress()返回的数组

EDIT Using hashCode() is an undocumented feature and there may be problems if you have both ipv6 and ipv4 addresses. 编辑使用hashCode()是一个未记录的功能,如果您同时拥有ipv6和ipv4地址可能会出现问题。 So it is best to compare arrays of bytes or convert them to a number by hand. 因此,最好比较字节数组或手动将它们转换为数字。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM