[英]sort a list of ips in ascending order
我有一個 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));
在不定義 function 以返回 ip 的每個部分的情況下,最簡單的實現方法是什么?
如果您將它們表示為像“192.168.2.4”這樣的自然字符串,那么它們將無法排序,但如果您為每個八位字節添加零前綴,例如“192.168.002.004”,那么字符串將按預期排序。 同樣,您可以用十六進制表示它們,例如“C0A80204”。 密鑰是每個八位字節的固定寬度。
或者,您可以將 4 個八位字節表示為一個數字。 需要注意的是,如果第一個八位字節是127或更高,那么一個32位的integer會把它當作一個負數,這會影響排序順序。 最簡單的解決方案(如果不是最節省內存的話)是將其作為 long 值返回。
這是一種方法。
List<InetAddress> ips = new ArrayList<>();
然后創建一些進行排序。 我正在演示.net4Address class 以接受點分四邊形或字節數組。 然后洗牌。
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);
根據源代碼, .net4Address
的hashCode
是地址本身。 這可以在不使用密鑰提取器的情況下用於排序。 但據我所知,它沒有記錄在案,因此不應依賴。 所以可以這樣做:
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
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.