码迷,mamicode.com
首页 > 其他好文 > 详细

关于TreeSet的排序对于删除操作的影响

时间:2014-09-21 19:25:31      阅读:173      评论:0      收藏:0      [点我收藏+]

标签:style   http   os   java   ar   div   sp   on   代码   

先贴上准备的代码:
  1. TreeSet<Node> list = new TreeSet<>();
  2. Node n1 = new Node(1);
  3. Node n2 = new Node(2);
  4. Node n3 = new Node(3);
  5. Node n4 = new Node(4);
  6. Node n5 = new Node(5);
这是Node,继承Comparable接口

  1. protected static class Node implements Comparable<Node>
  2. {
  3. public int id;
  4. private int __id;
  5. private static int ID = 1;
  6. public Node(int id) {
  7. this.id = id;
  8. this.__id = ID++;
  9. }
  10. @Override
  11. public String toString() {
  12. return "Node("+__id+") "+id;
  13. }
  14. @Override
  15. public int compareTo(Node o) {
  16. if(o.id>id)
  17. return 1;
  18. else if(o.id == id)
  19. return 0;
  20. else
  21. return -1;
  22. }
  23. }


TreeSet是一个二叉树集合,对于TreeMap的一个封装,增加一个元素,其实就是把元素当成Key,固定一个value放入TreeMap。
如果我们要研究TreeSet的排序,那么不得不了解TreeMap的Entry,其实就是一个二叉树结构,对于TreeSet本身来说,功能都是建立在TreeMap的基础上。
TreeMap$Entry拥有除了Key和Value之外,多了三个属性,left,right,parent。left和right作为二叉树的分叉,parent建立树的上下结构。
插入一个元素,都是根据比较器Compare出大小,然后从根节点开始,建立二叉树。所以在插入和删除的时候,有一个重要的地方,就是当你需要修改某一个元素的时候,必须确保这个元素的排序是没有被影响过的。比如我们上面一个列子,1-5个元素插入之后,当需要删除元素1,就必须保证,Node的id为1,如果id被修改成非1的情况下,再通过remove(Object obj)来删除就不能找到节点,因此删除就不可能了。

上测试例子:

  1. package examples.base;
  2. import java.util.TreeSet;
  3. public class TestTreeSet {
  4. public static void main(String[] args) {
  5. TreeSet<Node> list = new TreeSet<>();
  6. Node n1 = new Node(1);
  7. Node n2 = new Node(2);
  8. Node n3 = new Node(3);
  9. Node n4 = new Node(4);
  10. Node n5 = new Node(5);
  11. Node n = new Node(5);
  12. list.add(n1);
  13. list.add(n2);
  14. list.add(n3);
  15. list.add(n4);
  16. list.add(n5);
  17. list.add(n);
  18. System.out.println(list);
  19. System.out.println(list.higher(n3));
  20. n1.id = 5;
  21. if(list.remove(n1)){
  22. System.out.println("true");
  23. }
  24. list.add(n1);
  25. System.out.println(list);
  26. }
  27. protected static class Node implements Comparable<Node>
  28. {
  29. public int id;
  30. private int __id;
  31. private static int ID = 1;
  32. public Node(int id) {
  33. this.id = id;
  34. this.__id = ID++;
  35. }
  36. @Override
  37. public String toString() {
  38. return "Node("+__id+") "+id;
  39. }
  40. @Override
  41. public int compareTo(Node o) {
  42. if(o.id>id)
  43. return 1;
  44. else if(o.id == id)
  45. return 0;
  46. else
  47. return -1;
  48. }
  49. }
  50. }
结果:
  1. [Node(5) 5, Node(4) 4, Node(3) 3, Node(2) 2, Node(1) 1]
  2. Node(2) 2
  3. true
  4. [Node(1) 5, Node(4) 4, Node(3) 3, Node(2) 2, Node(1) 5]
删除成功其实只是删除了元素5,而元素1虽然id是5,但是它还是老的排序,所以在二叉树中是定位不到的,而因为id为5的元素存在,而且排序没有被影响,因此删除就能够成功。
最后,我们谨记一个要点:
当我们用TreeSet作为一个自动排序队列的时候,更新元素的位置,必须分三个步骤:
1、remove老的元素
2、修改
3、插入修改后的元素




关于TreeSet的排序对于删除操作的影响

标签:style   http   os   java   ar   div   sp   on   代码   

原文地址:http://www.cnblogs.com/chzcb/p/3984681.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!