简体   繁体   English

插入 HashMap 会导致排序混乱

[英]Inserting into HashMap messes with sorting

Based on this class基于此 class

public class Record {
    public static final String TABLE_NAME = "records";

    public static final String COLUMN_ID = "id";
    public static final String COLUMN_LONGITUDE = "longitude";
    public static final String COLUMN_LATITUDE = "latitude";
    public static final String COLUMN_SPEED = "speed";
    public static final String COLUMN_TIMESTAMP = "timestamp";

    private int id;
    private String longitude;
    private String latitude;
    private String speed;
    private String timestamp;

    public static final String CREATE_TABLE =
            "CREATE TABLE " + TABLE_NAME + "("
                + COLUMN_ID + " INTEGER PRIMARY KEY AUTOINCREMENT,"
                + COLUMN_LONGITUDE + " TEXT,"
                + COLUMN_LATITUDE + " TEXT,"
                + COLUMN_SPEED + " TEXT,"
                + COLUMN_TIMESTAMP + " TIMESTAMP DEFAULT (DATETIME('now','localtime'))"
            + ")";

    public Record(){
    }

    public Record(int id, String longitude, String latitude, String speed, String timestamp){
        this.id = id;
        this.longitude = longitude;
        this.latitude = latitude;
        this.speed = speed;
        this.timestamp = timestamp;
    }

    public int getId(){
        return id;
    }

    public String getLongitude(){
        return longitude;
    }

    public String getLatitude(){
        return latitude;
    }

    public String getSpeed(){
        return speed;
    }

    public String getTimestamp(){
        return timestamp;
    }

    public void setId(int id){
        this.id = id;
    }

    public void setLongitude(String longitude){
        this.longitude = longitude;
    }

    public void setLatitude(String latitude){
        this.latitude = latitude;
    }

    public void setSpeed(String speed){
        this.speed = speed;
    }

    public void setTimestamp(String timestamp){
        this.timestamp = timestamp;
    }
}

I have created my SQLite model我已经创建了我的 SQLite model

public class DatabaseHelper extends SQLiteOpenHelper {

    private static final int DATABASE_VERSION = 1;

    // Database Name
    private static final String DATABASE_NAME = "speeds";

    public DatabaseHelper(Context context) {
        super(context, DATABASE_NAME, null, DATABASE_VERSION);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL(Record.CREATE_TABLE);
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        db.execSQL("DROP TABLE IF EXISTS " + Record.TABLE_NAME);

        onCreate(db);
    }

    public void insertRecord(String longitude, String latitude, String speed){
        SQLiteDatabase db = this.getWritableDatabase();
        ContentValues values = new ContentValues();

        values.put(Record.COLUMN_LONGITUDE, longitude);
        values.put(Record.COLUMN_LATITUDE, latitude);
        values.put(Record.COLUMN_SPEED, speed);

        System.out.println("VALUEEEEEEEES" + values);

        db.insert(Record.TABLE_NAME, null, values);
        db.close();
    }

    public List<Record> getAllRecords(){
        List<Record> records = new ArrayList<>();

        String selectQuery = "SELECT * FROM " + Record.TABLE_NAME + " ORDER BY " + Record.COLUMN_TIMESTAMP + " DESC";

        SQLiteDatabase db = this.getWritableDatabase();
        Cursor cursor = db.rawQuery(selectQuery, null);

        if(cursor.moveToFirst()){
            do{
                Record record = new Record();
                record.setId(cursor.getInt(cursor.getColumnIndex(Record.COLUMN_ID)));
                record.setLongitude(cursor.getString(cursor.getColumnIndex(Record.COLUMN_LONGITUDE)));
                record.setLatitude(cursor.getString(cursor.getColumnIndex(Record.COLUMN_LATITUDE)));
                record.setSpeed(cursor.getString(cursor.getColumnIndex(Record.COLUMN_SPEED)));
                record.setTimestamp(cursor.getString(cursor.getColumnIndex(Record.COLUMN_TIMESTAMP)));

                records.add(record);
            } while (cursor.moveToNext());
        }
        db.close();

        return records;
    }

    public List<Record> getLastTenRecords(){
        List<Record> records = new ArrayList<>();

        String selectQuery = "SELECT * FROM " + Record.TABLE_NAME + " ORDER BY " + Record.COLUMN_TIMESTAMP + " DESC LIMIT 10";

        SQLiteDatabase db = this.getWritableDatabase();
        Cursor cursor = db.rawQuery(selectQuery, null);

        if(cursor.moveToFirst()){
            do{
                Record record = new Record();
                record.setId(cursor.getInt(cursor.getColumnIndex(Record.COLUMN_ID)));
                record.setLongitude(cursor.getString(cursor.getColumnIndex(Record.COLUMN_LONGITUDE)));
                record.setLatitude(cursor.getString(cursor.getColumnIndex(Record.COLUMN_LATITUDE)));
                record.setSpeed(cursor.getString(cursor.getColumnIndex(Record.COLUMN_SPEED)));
                record.setTimestamp(cursor.getString(cursor.getColumnIndex(Record.COLUMN_TIMESTAMP)));

                records.add(record);
            } while (cursor.moveToNext());
        }
        db.close();

        return records;
    }
}

Now, I am trying to show some data inside an ExpandableListView .现在,我试图在ExpandableListView中显示一些数据。 In my scenario i sort the response of the sql query by the COLUMN_TIMESTAMP and trying to parse it in the type of HashMap<String, List<String> in order for the ExpandableListView to recognize it.在我的场景中,我按COLUMN_TIMESTAMP对 sql 查询的响应进行排序,并尝试以HashMap<String, List<String>的类型对其进行解析,以便ExpandableListView识别它。

The problem is that even tho the result is sorted(and I can see it when looping and printing one by one), after I use this method to parse and put into HashMap, the sorting is gone.问题是即使结果是排序的(我可以在循环和打印时看到它),在我使用这种方法解析并放入 HashMap 之后,排序就消失了。

public static HashMap<String, List<String>> getLastTenData(Context context) {
        HashMap<String, List<String>> expandableListDetail = new HashMap<>();

        DatabaseHelper databaseHelper = new DatabaseHelper(context);

        List<Record> recordList = databaseHelper.getLastTenRecords();
        for(int i=0; i<recordList.size(); i++){
            List<String> myList = new ArrayList<>();
            myList.add("Y: "+recordList.get(i).getLatitude());
            myList.add("X: " + recordList.get(i).getLongitude());
            myList.add("Km/h: "+recordList.get(i).getSpeed());
            expandableListDetail.put(recordList.get(i).getTimestamp(), myList);
            System.out.println("check "+String.valueOf(i)+"    "+recordList.get(i).getTimestamp());
        }

        System.out.println(expandableListDetail);

        return expandableListDetail;
    }

What I mean is that expandableListDetail is not sorted by key when it should be.我的意思是, expandableListDetail不应该按键排序。 Any help?有什么帮助吗?

If have already ansered a similar question (regarding HashSet ) here .如果已经在这里回答了类似的问题(关于HashSet )。

Similar, a HashMap is unordered, so adding values to it and then iterating over the map will not yield items in the order you initially added them.类似地, HashMap是无序的,因此向其添加值然后迭代 map 将不会按照您最初添加的顺序生成项目。

Why does LinkedHashMap solve the issue?为什么LinkedHashMap能解决这个问题? (picking up on the idea from @Deadpool) (从@Deadpool 汲取灵感)

Hash table and linked list implementation of the Map interface, with predictable iteration order. Hash 表和 Map 接口的链表实现,具有可预测的迭代顺序。 This implementation differs from HashMap in that it maintains a doubly-linked list running through all of its entries.此实现与 HashMap 的不同之处在于,它维护一个双向链表,贯穿其所有条目。 This linked list defines the iteration ordering, which is normally the order in which keys were inserted into the map (insertion-order).这个链表定义了迭代顺序,通常是键插入 map 的顺序(插入顺序)。

Why does TreeMap solve the issue?为什么TreeMap能解决这个问题? (picking up on the idea from @tomgeraghty3) (从@tomgeraghty3 中汲取灵感)

The map is sorted according to the natural ordering of its keys map 根据其键的自然顺序排序

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM