基于索引值对列表进行排序

时间:2014-12-08 13:25:56

标签: java sorting hashset linkedhashset

这就是我到目前为止,我正在尝试根据索引的值对一堆 List<String>进行排序。

LinkedHashSet<List<String>> sorted = new LinkedHashSet<List<String>>();

如何按照List的最高到最低索引2值的顺序对LinkedHashSet进行排序?

示例输入:

List<String> data1 = Database.getData(uuid);
double price = Double.valueOf(data1.get(2))

data1.add("testval");
data1.add("testval");
data1.add("100.00");

sorted.add(data1);

并在另一个单独的名单上:

List<String> data2 = Database.getData(uuid);
double price = Double.valueOf(data2.get(2))

data2.add("anotherval");
data2.add("anotherval");
data2.add("50.00");

sorted.add(data2);

以强降序输出 sorted LinkedHashSet

testval testval 100.00
anotherval anotherval 50.00

很抱歉,如果这令人困惑,我不知道在哪里进行这样的排序。

3 个答案:

答案 0 :(得分:3)

首先,从Oracle's Java reference中提取:

  

此链接列表定义迭代排序,即元素插入集合

的顺序

因此,只需将数据插入LinkedHashSet即可对数据进行排序。 您可能会将该实现与SortedSet混淆。 SortedSet允许您传递比较器,该比较器将确定数据结构中的元素顺序。

另一方面,我不知道您是否随意选择了List<String>,但在我看来,将3个字符串聚合为类属性似乎更明智。关键是,如果你的元素总是3个元素,那么最后一个元素是一个双重值:为什么你需要一个动态结构作为List

修改

在这里,你可以更好地实现你想要的东西:

public class Element
{
    public Element(String a, String b, double val) {
        this.a = a;
        this.b = b;
        this.val = val;
    }

    @Override
    public String toString() {
        return a + "\t" + b + "\t" + val;
    }

    public String a;
    public String b;
    public double val;
}

您可以使用此类来存储元素。使用示例:

 SortedSet<Element> sorted = new TreeSet<>(new Comparator<Element>() {
        @Override
        public int compare(Element o1, Element o2) {
            return (new Double(o1.val)).compareTo(o2.val);
        }
    });

sorted.add(new Element("testval", "testval", 100.0));
sorted.add(new Element("anotherval", "anotherval", 50.0));
for(Element el: sorted)
{
    System.out.println(el);
}

请注意,比较器是作为实现Java Comparator接口的anonympous内部类的实例给出的。

答案 1 :(得分:3)

  • 首先,您不应该使用LinkedHashSet而是使用TreeSetLinkedHashSet将保留插入订单而不进行排序。
  • 其次,您需要使用TreeSet初始化Comparator,并根据List所需的值进行比较,即如果您知道提前代表String值的double的索引。否则,我建议使用自定义对象而不是List

如果您决定使用自定义对象,则无需使用TreeSet作为第二个参数初始化Comparator

相反,您可以让自定义对象实现Comparable,并在那里实现一次性比较逻辑。

这完全取决于您是否只需要按特定顺序排序。

最后,自定义对象需要您覆盖equalshashCode

答案 2 :(得分:3)

创建一个新类来表示复杂对象。当您可以在对象中执行此操作时,无需在列表中存储多个值。

public class ComplexObject {
    private String description1;
    private String description2;
    private Double value;

    public ComplexObject(String description1, String description2, Double value) {
        this.description1 = description1;
        this.description2 = description2;
        this.value = value;
    }

    public void setDescription1(String description1) {
        this.description1 = description1;
    }

    public String getDescription1() {
        return description1;
    }

    public void setDescription2(String description2) {
        this.description2 = description2;
    }

    public String getDescription2() {
        return description2;
    }

    public void setValue(Double value) {
        this.value = value;
    }

    public Double getValue() {
        return value;
    }
}

然后将元素添加到列表中并使用新的自定义比较器对其进行排序:

public static void main(String[] args) {

    List<ComplexObject> complexObjectList = new ArrayList<ComplexObject>();

    //add elements to the list
    complexObjectList.add(new ComplexObject("testval","testval",100.00d));
    complexObjectList.add(new ComplexObject("anotherval","anotherval",50.00d));

    //sort the list in descending order based on the value attribute of complexObject
    Collections.sort(complexObjectList, new Comparator<ComplexObject>() {
            public int compare(ComplexObject obj1, ComplexObject obj2) {
                return obj2.getValue().compareTo(obj1.getValue()); //compares 2 Double values, -1 if less , 0 if equal, 1 if greater
            }
        });

    //print objects from sorted list
    for(ComplexObject co : complexObjectList){
        System.out.println(co.getDescription1()+" "+co.getDescription2()+" "+co.getValue());
    }
}

输出:

testval testval 100.0
anotherval anotherval 50.0