我有一个ip对象列表,它们的v4地址作为字符串。(ip为十进制)
现在,我想用ip部件作为搜索键,按升序排序这个列表。
这是我的第一个方法。它可以工作,但是它需要四个函数来返回ip的每个部分。
Comparator<IP> ipComparator =
Comparator
.comparing(IP::getFirstPart)
.thenComparing(IP::getSecondPart)
.thenComparing(IP::getThirdPart)
.thenComparing(IP::getFourthPart);我想做这样的事
Comparator<IP> ipComparator =
Comparator
.comparing(IP::getPart(0))
.thenComparing(IP::getPart(1))
.thenComparing(IP::getPart(2))
.thenComparing(IP::getPart(3));在不定义返回ip的每个部分的函数的情况下,实现这一点的最简单方法是什么?
发布于 2022-02-27 03:48:19
这里有一种方法。
List<InetAddress> ips = new ArrayList<>();然后创建一些来分类。我正在演示Inet4Address类,以接受点四边形或字节数组。那就洗牌吧。
for (int i = 1; i < 23; i+= 2) {
ips.add(Inet4Address.getByName("192.168.1."+i));
ips.add(Inet4Address.getByAddress(new byte[]{(byte)192, (byte)168,
(byte)1, (byte)(i+1)}));
}
Collections.shuffle(ips);根据源代码,hashCode for Inet4Address是地址本身。不需要使用密钥提取器就可以进行排序。但据我所知,它没有被记录在案,因此不应该被依赖。因此,可以这样做:
ByteBuffer包装从getAddress()返回的字节数组并检索int值。ips.sort(Comparator.comparing(ip->
ByteBuffer.wrap(ip.getAddress()).getInt(),
(i1, i2) -> Integer.compareUnsigned(i1, i2)));现在打印结果。
ips.forEach(ip->System.out.println(ip.getHostAddress()));版画
192.168.1.1
192.168.1.2
192.168.1.3
192.168.1.4
192.168.1.5
192.168.1.6
192.168.1.7
192.168.1.8
192.168.1.9
192.168.1.10
192.168.1.11
192.168.1.12
192.168.1.13
192.168.1.14
192.168.1.15
192.168.1.16
192.168.1.17
192.168.1.18
192.168.1.19
192.168.1.20
192.168.1.21
192.168.1.22发布于 2022-02-27 03:04:42
如果你用"192.168.2.4“这样的自然字符串来表示它们,那么它们就不会是可排序的,但是如果你对每个八进制进行零前缀,比如"192.168.002.004”,那么字符串就会按预期排序。类似地,您可以用十六进制表示它们,如"C0A80204“。每个八进制键的宽度是固定的。
或者,您可以将4位数表示为单个数字。需要注意的是,如果第一个八进制数是127或更高,那么32位整数就会把它当作一个负数,这会影响排序顺序。最简单的解决方案(如果不是最节省内存的话)是将它作为一个长值返回。
https://stackoverflow.com/questions/71281746
复制相似问题