HashMap<String, String> 的 ArrayList 的不同排序方式

different ways of sorting ArrayList of of HashMap<String, String>

有很多与此相关的问题建议使用 Comparator 来比较和排序数据,我已经在尝试并努力让它发挥作用,所以请不要将其报告为重复。

我有一个 HashMap<String, String>

的数组列表
ArrayList<HashMap<String, String>>

并以这种形式在此列表中包含数据,

title , linknumber 是键。

{ {title="",link="",number=}, {title="",link="",number=}, {title="",link="",number=} }

示例,

{ {title,link,number = 8}, {title,link,number = 1}, {title,link,number = 3} }

应该改为,

{ {title,link,number = 1}, {title,link,number = 3}, {title,link,number = 8} }

我想根据数字排序,我试过了,

我创建了一个新的 class(如许多 post 中所建议的那样创建新的 class 来比较数据),它实现了 Comparator。

public class SortData implements Comparator<ArrayList<HashMap<String, String>>> 

自动执行的方法是,

@Override
    public int compare(ArrayList<HashMap<String, String>> lhs,
            ArrayList<HashMap<String, String>> rhs) {


        return 0;
    }

现在这个方法建议用两个Hashmap的arraylist来比较,但是我只有一个arraylist需要排序,那么第二个arraylist应该用什么?

我的 Arraylist 名称是 SecondArray,我想将它的每个值与下一个值进行比较,

 @Override
        public int compare(ArrayList<HashMap<String, String>> lhs,
                ArrayList<HashMap<String, String>> rhs) {

                lhs = SecondArray;
                rhs = // How to compare to the next value of the same Array ? 
            return 0;
        }

我应该如何比较同一个数组列表和下一个值?

更新: 每个 Array 列表元素有三个 key/value 对,其中一个是一个数字,我想根据那个数字对 arraylist 进行排序,这意味着 key/value 对具有最小的数字应该在数组列表中排在第一位。

在对 Map 中的 List 进行排序时,您希望根据键 "number" 进行排序,我认为您应该改用它:

    Collections.sort(myList, new Comparator<Map<String, String>>() {
        @Override
        public int compare(final Map<String, String> o1, final Map<String, String> o2) {
            // Do your sorting...
            return Integer.valueOf(o1.get("number"))
                          .compareTo(Integer.valueOf(o2.get("number")));
        }
    });

或者,如果您使用 Java 8,您可以像这样对 Map 中的 List 进行排序:

final List<Map<String, String>> sorted = 
    myList.stream()
          .sorted((m1, m2) -> Integer.valueOf(m1.get("number"))
                                     .compareTo(Integer.valueOf(m2.get("number"))))
          .collect(Collectors.toList());

看来你误解了比较器的概念。这个 class 应该提供决定是否应该交换集合中的两个元素的方法,所以它专注于集合的 content

public class SortData implements Comparator<HashMap<String, String>>
//                                          ^^^^^^^^^^^^^^^^^^^^^^^

不是

public class SortData implements Comparator<ArrayList<HashMap<String, String>>>
// this would sort collection of -----------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 
// like List<ArrayList<HashMap<String, String>>>

还假设 {title,link,number} 是地图中的键,您的 compare 代码可能看起来像

public int compare(HashMap<String, String> o1, HashMap<String, String> o2) {
    int nr1= Integer.parseInt(o1.get("number"));
    int nr2= Integer.parseInt(o2.get("number"));
    return Integer.compare(nr1, nr2);
}

但是如果您确定 Map 将仅保存 titlelinknumber 的值,那么我会为这个结构创建单独的 class,例如

class Data{//you should also pick better name :)
    private String title;
    private String link;//you can also use URL here instead of String,
    private int number;
    //add getters and setters for each field like
    public int getNumber(){
        return number;
    }
}

这样你的比较器会更简单

public class SortData implements Comparator<Data>{

    @Override
    public int compare(Data o1, Data o2) {
        return Integer.compare(o1.getNumber(), o2.getNumber());
    }
}

或者实际上从 Java 8 开始,您甚至不需要明确地创建单独的比较器 class。您可以使用 Lambdas

隐式执行此操作
Comparator<Data> numberComparator =  (o1,o2)->Integer.compare(o1.getNumber(), o2.getNumber());

如果你想缩短你的代码,你也可以使用方法引用

COmparator<Data> numberComparator = Comparator.comparingInt(Data::getNumber);

现在你的列表

List<Data> list = ...

可以这样排序

list.sort(numberComparator);

list.sort(Comparator.comparingInt(Data::getNumber));

将工具更改为Comparator<Hashmap<String,String>>并使用:

public int compare(HashMap<String, String>> lhs,
        HashMap<String, String>> rhs) {
    return Integer.compare(Integer.parseInt(lhs.get("number")),
        Integer.parseInt(rhs.get("number")));
}

我假设您指的是(哈希)映射列表。

强烈建议 为 3 个变量制作一个数据保存 class,然后 class 实现 Comarable (you could make a separate class that implements Comparator 就像你展示的那样, 但我发现这更复杂)

实施可比较后,您可以使用 Collections.sort 对列表进行排序。

这里我编写了一个简短的例子:

import java.util.*;
import java.lang.*;
import java.io.*;

class Data implements Comparable<Data>
{
    public static void main (String[] args) throws java.lang.Exception
    {
        List<Data> data = new ArrayList<Data>();
        data.add(new Data("Title1", "Link1", 8));
        data.add(new Data("Title2", "Link2", 1));
        data.add(new Data("Title3", "Link3", 3));

        for(Data d : data)
        {
            System.out.print(d.getNumber() + " ");
        }

        System.out.println();

        Collections.sort(data);

        for(Data d : data)
        {
            System.out.print(d.getNumber() + " ");
        }
    }

    private String title;
    private String link;
    private int number;

    public Data(){}
    public Data(String title, String link, int number)
    {
        setTitle(title);
        setLink(link);
        setNumber(number);
    }
    public void setTitle(String title)
    {
        this.title = title;
    }

    public void setLink(String link)
    {
        this.link = link;
    }

    public void setNumber(int number)
    {
        this.number = number;
    }

    public String getTitle()
    {
        return title;
    }

    public String getLink()
    {
        return link;
    }

    public int getNumber()
    {
        return number;
    }

    @Override
    public int compareTo(Data data)
    {
        return this.getNumber() - data.getNumber();
    }
}

输出:

8 1 3 
1 3 8 

您可以在 Ideone

试试这个

不使用 Comparator class 并简单地实施冒泡排序怎么样?

像这样,

for (int c = 0; c < (yourArrayList.size() - 1); c++) {
            for (int d = 0; d < (yourArrayList.size() - c - 1); d++) {

                if (Integer.parseInt(yourArrayList.get(d).get("number")) > Integer
                        .parseInt(yourArrayList.get(d + 1).get("number"))) {

                    temporary = yourArrayList.get(d);
                    yourArrayList.set(d, yourArrayList.get(d + 1));
                    yourArrayList.set(d + 1, temporary);

                }
            }
        }

看这个例子,

import java.util.ArrayList;
import java.util.HashMap;

public class Main {

    public static void main(String[] args) {

        ArrayList<HashMap<String, String>> yourArrayList = 
                new ArrayList<HashMap<String, String>>();

        HashMap<String, String> myHashMap = new HashMap<String, String>();

        myHashMap.put("title", "first Title");
        myHashMap.put("date", "This is 1st date");
        myHashMap.put("number", "5");
        yourArrayList.add(0, myHashMap);

        myHashMap = new HashMap<String, String>();

        myHashMap.put("title", "Second Title");
        myHashMap.put("date", "This is 2nd date");
        myHashMap.put("number", "2");
        yourArrayList.add(1, myHashMap);

        myHashMap = new HashMap<String, String>();

        myHashMap.put("title", "Third Title");
        myHashMap.put("date", "This is 3rd date");
        myHashMap.put("number", "7");
        yourArrayList.add(2, myHashMap);

        myHashMap = new HashMap<String, String>();

        myHashMap.put("title", "Fourth Title");
        myHashMap.put("date", "This is 4th date");
        myHashMap.put("number", "0");
        yourArrayList.add(3, myHashMap);

        System.out.println("=================");
        System.out.println("BEFORE SORTING");
        System.out.println("=================");

        for (int i = 0; i < yourArrayList.size(); i++) {
            System.out.println(yourArrayList.get(i));
        }

        HashMap<String, String> temporary;

        for (int c = 0; c < (yourArrayList.size() - 1); c++) {
            for (int d = 0; d < (yourArrayList.size() - c - 1); d++) {

                if (Integer.parseInt(yourArrayList.get(d).get("number")) > Integer
                        .parseInt(yourArrayList.get(d + 1).get("number"))) {

                    temporary = yourArrayList.get(d);
                    yourArrayList.set(d, yourArrayList.get(d + 1));
                    yourArrayList.set(d + 1, temporary);

                }
            }
        }

        System.out.println("=================");
        System.out.println("AFTER SORTING");
        System.out.println("=================");

        for (int i = 0; i < yourArrayList.size(); i++) {
            System.out.println(yourArrayList.get(i));
        }

    }

}

输出,

=================
BEFORE SORTING
=================
{date=This is 1st date, number=5, title=first Title}
{date=This is 2nd date, number=2, title=Second Title}
{date=This is 3rd date, number=7, title=Third Title}
{date=This is 4th date, number=0, title=Fourth Title}
=================
AFTER SORTING
=================
{date=This is 4th date, number=0, title=Fourth Title}
{date=This is 2nd date, number=2, title=Second Title}
{date=This is 1st date, number=5, title=first Title}
{date=This is 3rd date, number=7, title=Third Title}

你可以在这里测试 -> http://goo.gl/0M3rBf