2012-03-30 117 views
1

我正在使用'ConcurrentSkipListMap'(因为我的环境是多线程的)和一个'比较器'根据它的Id &日期对插入对象进行排序。在'TestObject'中它的名字将是唯一的。所以我用它作为我的'钥匙'在地图上。 'Id'将是一个任意值。我需要根据'Id'和'date'值对我的地图进行排序(如果ID相同,则按日期排序),因为我只是添加当前日期并将焦点放在ID字段上。但是地图并没有让我知道排序顺序。ConcurrentSkipListMap使用比较器排序

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); 
} 

}

而对象类是 -

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; 
} 

}

缺货片段是 -

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

预期订单是 -

Obj_3(由于ID = 0),Obj_1, Obj_10,(Ids = 1),Obj_2(Id = 2)

任何人都可以请指出我在这里做错了什么?提前致谢。

+0

'ConcurrentSkipListMap'是按键排序的,而不是值。坦率地说,我认为没有任何类型安全的方法可以通过Java中的值对可变映射进行排序。 – 2012-03-30 19:09:31

回答

3

该图比较键而不是值。即它是按字母顺序排列的。


P.S.还需要用比较器作为构造函数参数初始化映射。但在这种情况下,它不起作用,因为比较器应该比较字符串(键)。

1

您尚未向比较仪提供您的ConcurrentSkipListMap的构造函数。

参见:

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

由于比较空,在实现中使用的钥匙,在这种情况下是字符串值的自然顺序。

+0

即使我将该比较器传递给构造函数,这不会被修复。需要想出办法,减去字符串前缀(“Obj_”)并比较它并返回。我认为它应该工作。 – Sam 2012-03-31 02:17:19

0

TreeMap和ConcurrentSkipListMap只能通过Key进行排序,如果要按不确定值排序,可以用构造方法创建一个内部Comparator类,当你通过TestComparator的新实例传递“map”时private static Map<String, TestObject> map = new ConcurrentSkipListMap<String, TestObject>(); Then new new TreeMap该参数与之前的“比较对象”相对应。最后将“映射”映射到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); 
} 

}`

我不认为对代码的效率,它只是实现的功能。