简体   繁体   English

ConcurrentSkipListMap使用Comparator排序

[英]ConcurrentSkipListMap Sorting Using Comparator

I am using 'ConcurrentSkipListMap' (Since my environment will be multythreaded) and a 'Comparator' to sort the inserting object according to its Id & date. 我正在使用'ConcurrentSkipListMap'(因为我的环境将是多线程的)和'Comparator'来根据其Id和日期对插入对象进行排序。 in the 'TestObject' its Name will be unique. 在'TestObject'中,它的名称将是唯一的。 so i used it as my 'key' in the map. 所以我在地图中用它作为我的“钥匙”。 'Id' will be a arbitrary value. 'Id'将是一个任意值。 i need to sort my map according to the 'Id' and 'date' values.(if Id s are equal will sort it by date) for here i just add current date and gave the focus on the ID field. 我需要根据'Id'和'date'值对我的地图进行排序。(如果Id s相等会按日期排序)这里我只需添加当前日期并将焦点放在ID字段上。 But map didn't return me the sorting order i expect. 但是地图没有给我回复我期望的排序顺序。

public class SortTest {

private static final Comparator TEST_COMPARATOR = new TestComparator();
private static Map<String, TestObject> map = new ConcurrentSkipListMap<String, TestObject>();

private static class TestComparator<T> implements Comparator<TestObject> {

    @Override
    public int compare(TestObject o1, TestObject o2) {
        Integer x1 = o1.getId();
        Integer x2 = o2.getId();

        int Comp = x1.compareTo(x2);

        if (Comp != 0) {
            return Comp;
        } else {

            Date d1 = o1.getDate();
            Date d2 = o2.getDate();

            return d1.compareTo(d2);
        }
    }

}

public static void construct() {

    for (int i = 1; i <= 10; i++) {
        TestObject t = new TestObject();
        t.setId(i%3);
        t.setDate(new Date());
        t.setName("Obj_"+i);
        System.out.println(t);
        map.put(t.getName(),t);


    }

}
public static void main(String[] args) {
    SortTest x = new SortTest();
    x.construct();
    System.out.println(map);
}

} }

And the ObjectClass is - 而ObjectClass是 -

public class TestObject {

private String name;

private int id;

Date date;

public int getId() {
    return id;
}

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

public Date getDate() {
    return date;
}

public void setDate(Date date) {
    this.date = date;
}

public String getName() {
    return name;
}

public void setName(String name) {
    this.name = name;
}

/* (non-Javadoc)
 * @see java.lang.Object#hashCode()
 */
@Override
public int hashCode() {
    final int prime = 31;
    int result = 1;
    result = prime * result + ((name == null) ? 0 : name.hashCode());
    return result;
}



/* (non-Javadoc)
 * @see java.lang.Object#toString()
 */
@Override
public String toString() {
    return "TestObject [name=" + name + ", id=" + id + "]";
}

/* (non-Javadoc)
 * @see java.lang.Object#equals(java.lang.Object)
 */
@Override
public boolean equals(Object obj) {
    if (this == obj)
        return true;
    if (obj == null)
        return false;
    if (getClass() != obj.getClass())
        return false;
    TestObject other = (TestObject) obj;
    if (name == null) {
        if (other.name != null)
            return false;
    } else if (!name.equals(other.name))
        return false;
    return true;
}

} }

Out snippet is - 输出片段是 -

{Obj_1=TestObject [name=Obj_1, id=1], Obj_10=TestObject [name=Obj_10, id=1], Obj_2=TestObject [name=Obj_2, id=2], Obj_3=TestObject [name=Obj_3, id=0],...... {Obj_1 = TestObject [name = Obj_1,id = 1],Obj_10 = TestObject [name = Obj_10,id = 1],Obj_2 = TestObject [name = Obj_2,id = 2],Obj_3 = TestObject [name = Obj_3,id = 0],......

Expected Order is - 预期订单是 -

Obj_3(Since Id =0 ),Obj_1,Obj_10, (Ids are =1 ), Obj_2 (Id =2) Obj_3(因为Id = 0),Obj_1,Obj_10,(Ids = 1),Obj_2(Id = 2)

Can anyone please point me out what i am doing wrong here? 任何人都可以指出我在这里做错了什么? Thanks in advance. 提前致谢。

The map compares keys, not values. 地图比较键,而不是值。 Ie it is ordered in alphabet string order for keys. 即按键的字母串顺序排序。


PS also you need to initialize the map with the comparator as a constructor parameter. PS你还需要用比较器初始化地图作为构造函数参数。 But in this case it won't work, as comparator should compare Strings (keys). 但是在这种情况下它不起作用,因为比较器应该比较字符串(键)。

You haven't supplied the Comparator to the constructor of your ConcurrentSkipListMap . 您尚未将Comparator提供给ConcurrentSkipListMap的构造函数。

See: 看到:

http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/ConcurrentSkipListMap.html http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/ConcurrentSkipListMap.html

Because the Comparator is null, the implementation uses the natural ordering of the keys, which in this case are String values. 因为Comparator为null,所以实现使用键的自然排序,在本例中是键值。

TreeMap and ConcurrentSkipListMap can only sort by Key,if you want sort by uncertain Values ,you can create an inner Comparator class with a construction method ,when you new instance the TestComparator you pass the "map" private static Map<String, TestObject> map = new ConcurrentSkipListMap<String, TestObject>(); TreeMap和ConcurrentSkipListMap只能按Key排序,如果要按不确定值排序,可以使用构造方法创建一个内部Comparator类,当你的新实例TestComparator传递“map” private static Map<String, TestObject> map = new ConcurrentSkipListMap<String, TestObject>(); Then new a TreeMap the parameter with previous "Comparator object".At last put the "map" to TreeMap code like this:`public class SortTest { private static Map map = new ConcurrentSkipListMap(); 然后用一个先前的“Comparator对象”新建一个TreeMap参数。最后将“map”放到TreeMap代码中,如下所示:`public class SortTest {private static Map map = new ConcurrentSkipListMap();

private static class TestComparator<String> implements Comparator<String> {
    Map<String, TestObject> tmp;

    public TestComparator(Map<String, TestObject> map) {
        this.tmp = map;
    }

    /*
     * (non-Javadoc)
     * 
     * @see java.util.Comparator#compare(java.lang.Object, java.lang.Object)
     */
    public int compare(String o1, String o2) {
        Integer x1 = tmp.get(o1).getId();
        Integer x2 = tmp.get(o2).getId();
        int Comp = x1.compareTo(x2);

        if (Comp != 0) {
            return Comp;
        } else {

            Date d1 = tmp.get(o1).getDate();
            Date d2 = tmp.get(o2).getDate();
            return d1.compareTo(d2);
        }
    }

}

public static void construct() {

    for (int i = 1; i <= 10; i++) {
        TestObject t = new TestObject();
        t.setId(i % 3);
        t.setDate(new Date());
        t.setName("Obj_" + i);
        System.out.println(t);
        map.put(t.getName(), t);

    }

}
public static void main(String[] args) {
    SortTest x = new SortTest();
    x.construct();
    System.out.println(map);
    TestComparator comparator = new TestComparator(map);
    TreeMap<String, TestObject> sorted_map = new TreeMap<String, TestObject>(comparator);
    sorted_map.putAll(map);
    System.out.println(sorted_map);
}

}` }`

I don't think about the efficiency of the code ,it just realizes the function. 我没有考虑代码的效率,它只是实现了功能。

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

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