[問題] Collections.sort() を使用してリスト コレクションを並べ替える

背景:最近、比較的典型的な問題である、リスト コレクションの順序が異なる
ソートの問題を特定したので、ここで共有したいと思います。

問題の説明:
コレクションCollections.sort()メソッドを使用してリストを収集する排序と、並べ替えられた結果に問題が表示されます乱序问题。問題のコードは次のとおりです:

車の記録.java:

package com.sk.bean;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@NoArgsConstructor
@AllArgsConstructor
public class CarRecord implements Comparable<CarRecord> {
    
    

    private Integer id;
    private String plateCode;
    private Long passTime;

    @Override
    public int compareTo(CarRecord o) {
    
    
        return (int) (o.passTime - this.passTime);
    }
}

テスト.java

package com.sk.test;

import com.sk.bean.CarRecord;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;

public class Test01 {
    
    

    public static void main(String[] args) {
    
    
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        List<CarRecord> list = new ArrayList<>();
        list.add(new CarRecord(1, "鲁A 12345", 1688634366000L));
        list.add(new CarRecord(2, "鲁A 12346", 1688568125000L));
        list.add(new CarRecord(3, "鲁A 12347", 1688504221000L));
        list.add(new CarRecord(4, "鲁A 12348", 1686144663000L));
        list.add(new CarRecord(5, "鲁A 12349", 1686094000000L));
        list.add(new CarRecord(5, "鲁A 12349", 1686043339000L));
        list.add(new CarRecord(5, "鲁A 12349", 1685992410000L));
        Collections.sort(list);
        list.stream().forEach(x -> {
    
    
            System.out.println(x.toString() + "  时间:" + sdf.format(new Date(x.getPassTime())));
        });
    }
}

結果:

CarRecord(id=4, plateCode=A 12348, passTime=1686144663000)  时间:2023-06-07 21:31:03
CarRecord(id=5, plateCode=A 12349, passTime=1686094000000)  时间:2023-06-07 07:26:40
CarRecord(id=5, plateCode=A 12349, passTime=1686043339000)  时间:2023-06-06 17:22:19
CarRecord(id=5, plateCode=A 12349, passTime=1685992410000)  时间:2023-06-06 03:13:30
CarRecord(id=1, plateCode=A 12345, passTime=1688634366000)  时间:2023-07-06 17:06:06
CarRecord(id=2, plateCode=A 12346, passTime=1688568125000)  时间:2023-07-05 22:42:05
CarRecord(id=3, plateCode=A 12347, passTime=1688504221000)  时间:2023-07-05 04:57:01

フィールドごとに並べ替え、実行結果を観察すると、データのフィールドの順序が間違っているpassTimeことが明らかにわかります。passTime

問題の原因:
コードを分析したところ、コード内で問題が発生していることがわかりました(int) (o.passTime - this.passTime)。Java の値の Long 型と int 型の戻り長が同じではないことがわかりました。int 型はデータ損失の原因となります;
注:
**int**値の範囲は ( -2147483648~2147483647) で、4 バイト (-2 ~ 2 の 31 乗 - 1) を占めます。
**long**値の範囲は ( -9223372036854774808~9223372036854774807) で、8 バイトを占めます。 バイト (-2 ~ 2 の 63 乗~ 2の63乗-1);
id3~id4の通過時間値:1688504221000-1686144663000=2359558000 > 2147483647
上記からわかるように、同じ年、月の通過時間の差はint値の時間範囲内であるため、同じデータ年と月の順序になります。

問題が解決しました:

コードの変更:(int) (o.passTime - this.passTime)次のように変更しますcompare(o.passTime, this.passTime)

Collections.sort(list, new Comparator<Long>() {
    
    
    @Override
    public int compare(Long l1, Long l2) {
    
    
        return Long.compare(l1,l2);
    }
});

compare()次のようにメソッドのソース コードを表示します。

public static int compare(long x, long y) {
    
    
        return (x < y) ? -1 : ((x == y) ? 0 : 1);
}

変更された実行結果:

CarRecord(id=1, plateCode=A 12345, passTime=1688634366000)  时间:2023-07-06 17:06:06
CarRecord(id=2, plateCode=A 12346, passTime=1688568125000)  时间:2023-07-05 22:42:05
CarRecord(id=3, plateCode=A 12347, passTime=1688504221000)  时间:2023-07-05 04:57:01
CarRecord(id=4, plateCode=A 12348, passTime=1686144663000)  时间:2023-06-07 21:31:03
CarRecord(id=5, plateCode=A 12349, passTime=1686094000000)  时间:2023-06-07 07:26:40
CarRecord(id=5, plateCode=A 12349, passTime=1686043339000)  时间:2023-06-06 17:22:19
CarRecord(id=5, plateCode=A 12349, passTime=1685992410000)  时间:2023-06-06 03:13:30

Alibaba の「Java 開発マニュアル」の Collections.sort() の仕様要件は次のとおりです。
ここに画像の説明を挿入します

おすすめ

転載: blog.csdn.net/weixin_37598243/article/details/131612230