我有一個 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每個部分的函式的情況下實作這一點的最簡單方法是什么?
uj5u.com熱心網友回復:
這是一種方法。
- 創建一個串列來保存 IP 地址。
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);
根據源代碼hashCodeforInet4Address是地址本身。這可以在不使用密鑰提取器的情況下用于排序。但據我所知,它沒有記錄在案,因此不應依賴。所以可以這樣做:
- 使用 a
ByteBuffer包裝從回傳的位元組陣列getAddress()并檢索int值。 - 然后。由于高位可以任意出現在 IP 地址中,因此對排序應用的兩個 ip 進行無符號比較
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
uj5u.com熱心網友回復:
如果您將它們表示為像“192.168.2.4”這樣的自然字串,那么它們將無法排序,但如果您對每個八位位元組加零前綴,例如“192.168.002.004”,那么字串將按預期排序。同樣,您可以用十六進制表示它們,例如“C0A80204”。密鑰是每個八位位元組的固定寬度。
或者,您可以將 4 個八位位元組表示為一個數字。需要注意的是,如果第一個八位位元組為 127 或更高,那么 32 位整數會將其視為負數,這會影響排序順序。最簡單的解決方案(如果不是最節省記憶體的話)是將它作為長值回傳。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/437133.html
上一篇:嘗試快速排序結構陣列時遇到問題
