问题
In Java, i have an arrayList of ip address. how do i find the min and max ?
I have used the Collection.min() but it doesnt work given a case like :
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. I would need to do this operation per tick (each tick is at 5 sec interval). The number of IP address would hit a max of probably 300.
回答1:
Convert the IP address into a long integer, then sort it. 192.168.0.1
can be converted to an integer using binary arithmetic/operators:
( 192 << 24 ) + ( 168 << 16 ) + ( 0 << 8 ) + ( 1 << 0 )
and so on. Do read the comments below about using the correct data type.
回答2:
Are you storing the IP addresses as String
instances? This is likely the case, because String
are sorted lexicographically, meaning "10" < "2"
.
If you want to sort them numerically, there are several ways:
- Instead of putting them into a
List<String>
, put them into aList<Integer>
- or maybe even a
SortedSet<Integer>
- or maybe even a
- Keep the
List<String>
, but provide a custom comparator that convert theString
to numerical value for comparison- 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...
- may not be most efficient, but works without major changes to existing infrastructure
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
- java.util.Scanner
- java.util.SortedSet
- java.util.Comparator
回答3:
Referring to 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;
}
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. To obtain a sorted String of ip addresses.
Thanks
回答4:
If you treat the IP addresses as an integer (long), you can then sort on it. 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.
//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".
回答5:
In case you don't want to parse the IP by hand, you can use InetAddress
class
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. You can also compare arrays returned by InetAddress.getAddress()
EDIT Using hashCode()
is an undocumented feature and there may be problems if you have both ipv6 and ipv4 addresses. So it is best to compare arrays of bytes or convert them to a number by hand.
来源:https://stackoverflow.com/questions/2808930/given-a-list-of-ip-address-how-do-you-find-min-max