疯狂JAVA讲义---第七章(上):集合set

本文深入讲解Java集合框架的核心部分,包括HashSet、LinkedHashSet、TreeSet和EnumSet等集合类的使用方法及内部实现原理,同时介绍了如何重写equals和hashcode方法以及实现定制排序。

集合是j2se中非常重要的一部分,和我前面花了一个星期讲的面向对象是java基础的两座大山。首先我先给个这部分的结构图

我先列些基础操作:foreach遍历集合

  1. public class TestForeach
  2. {
  3.     public static void main(String[] args) 
  4.     {
  5.         //创建一个集合
  6.         Collection books = new HashSet();
  7.         books.add(new String("轻量级J2EE企业应用实战"));
  8.         books.add(new String("Struts2权威指南"));
  9.         books.add(new String("基于J2EE的Ajax宝典"));
  10.         for (Object obj : books)
  11.         {
  12.             String book = (String)obj;
  13.             System.out.println(book);
  14.             if (book.equals("Struts2权威指南"))
  15.             {
  16.                 //下面代码会引发ConcurrentModificationException异常
  17.                 books.remove(book);
  18.             }
  19.         }
  20.         System.out.println(books);
  21.     }
  22. }

现在开始正式讲集合,先讲set中最重要的HashSet

集合HashSet的重点是要学会重写其equals和hashcode的方法

注意:应该尽量保证两个对象通过equals比较返回true,他们的hashcode返回也相等

大家可以通过下面的代码来体会其中的奥秘,eg

  1. class A
  2. {
  3.     public boolean equals(Object obj)
  4.     {
  5.         return true;
  6.     }
  7. }
  8. //类B的hashCode()方法总是返回1,但没有重写其equals()方法
  9. class B
  10. {
  11.     public int hashCode()
  12.     {
  13.         return 1;
  14.     }
  15. }
  16. //类C的hashCode()方法总是返回2,但没有重写其equals()方法
  17. class C
  18. {
  19.     public int hashCode()
  20.     {
  21.         return 2;
  22.     }
  23.     public boolean equals(Object obj)
  24.     {
  25.         return true;
  26.     }
  27. }
  28. public class TestHashSet
  29. {
  30.     public static void main(String[] args) 
  31.     {
  32.         HashSet books = new HashSet();
  33.         //分别向books集合中添加2个A对象,2个B对象,2个C对象
  34.         books.add(new A());
  35.         books.add(new A());
  36.         books.add(new B());
  37.         books.add(new B());
  38.         books.add(new C());
  39.         books.add(new C());
  40.         System.out.println(books);
  41.     }
  42. }

HashSet最主要的优点是快。

然后讲下LinkedHashSet,他的优点是按照插入顺序排列,速度略慢,eg

    • public class TestLinkedHashSet
    • {
    •     public static void main(String[] args) 
    •     {
    •         LinkedHashSet books = new LinkedHashSet();
    •         books.add("Struts2权威指南");
    •         books.add("轻量级J2EE企业应用实战");
    •         //删除 Struts2权威指南
    •         books.remove("Struts2权威指南");
    •         //重新添加 Struts2权威指南
    •         books.add("Struts2权威指南");
    •         System.out.println(books);
    •     }
    • }

TreeSet具体原理用到了红黑树http://baike.baidu.com/view/133754.htm比较复杂

主要TreeSet会调用对象的compareTo进行元素比较,

自然排序(根据集合元素的大小,将他们以升序排列)eg

  1. class Z implements Comparable
  2. {
  3.     int age;
  4.     public Z(int age)
  5.     {
  6.         this.age = age;
  7.     }
  8.     public boolean equals(Object obj)
  9.     {
  10.         return false;
  11.     }
  12.     public int compareTo(Object obj)
  13.     {
  14.         return 1;
  15.     }
  16. }
  17. public class TestTreeSet
  18. {
  19.     public static void main(String[] args) 
  20.     {
  21.         TreeSet set = new TreeSet();
  22.         Z z1 = new Z(6);
  23.         set.add(z1);
  24.         System.out.println(set.add(z1));
  25.         //下面输出set集合,将看到有2个元素
  26.         System.out.println(set);
  27.         //修改set集合的第一个元素的age属性
  28.         ((Z)(set.first())).age = 9;
  29.         //输出set集合的最后一个元素的age属性,将看到也变成了9
  30.         System.out.println(((Z)(set.last())).age);
  31.     }
  32. }

定制排序:eg

  1. class M
  2. {
  3.     int age;
  4.     public M(int age)
  5.     {
  6.         this.age = age;
  7.     }
  8. }
  9. class N
  10. {
  11.     int age;
  12.     public N(int age)
  13.     {
  14.         this.age = age;
  15.     }
  16. }
  17. public class TestTreeSet3
  18. {
  19.     public static void main(String[] args) 
  20.     {
  21.         TreeSet ts = new TreeSet(new Comparator()
  22.         {
  23.             public int compare(Object o1, Object o2)
  24.             {
  25.                 int age1 = o1 instanceof M ? ((M)o1).age :((N)o1).age;
  26.                 int age2 = o1 instanceof M ? ((M)o2).age :((N)o2).age;
  27.                 return age1 - age2;
  28.                 /*
  29.                 M m1 = (M)o1;
  30.                 M m2 = (M)o2;
  31.                 if (m1.age > m2.age)
  32.                 {
  33.                     return -1;
  34.                 }
  35.                 else if (m1.age == m2.age)
  36.                 {
  37.                     return 0;
  38.                 }
  39.                 else
  40.                 {
  41.                     return 1;
  42.                 }
  43.                 */
  44.             }
  45.         }); 
  46.         ts.add(new M(5));
  47.         ts.add(new M(-3));
  48.         ts.add(new N(9));
  49.         System.out.println(ts);
  50.     }
  51. }

最后讲下EnumSet,这个是专为枚举类准备(具体知识请看我前几天的博客)这里我就举了例子,eg

  1. enum Season
  2. {
  3.     SPRING,SUMMER,FALL,WINTER
  4. }
  5. public class EnumSetDemo
  6. {
  7.     public static void main(String[] args) 
  8.     {
  9.         //创建一个EnumSet集合,集合元素就是Season枚举类的全部枚举值
  10.         EnumSet es1 = EnumSet.allOf(Season.class);
  11.         //输出[SPRING,SUMMER,FALL,WINTER]
  12.         System.out.println(es1);
  13.         //创建一个EnumSet空集合,指定其集合元素是Season类的枚举值。
  14.         EnumSet es2 = EnumSet.noneOf(Season.class); 
  15.         //输出[]
  16.         System.out.println(es2);
  17.         //手动添加两个元素
  18.         es2.add(Season.WINTER);
  19.         es2.add(Season.SPRING);
  20.         //输出[SPRING,WINTER]
  21.         System.out.println(es2);
  22.         //以指定枚举值创建EnumSet集合
  23.         EnumSet es3 = EnumSet.of(Season.SUMMER  , Season.WINTER); 
  24.         //输出[SUMMER,WINTER]
  25.         System.out.println(es3);
  26.         EnumSet es4 = EnumSet.range(Season.SUMMER  , Season.WINTER); 
  27.         //输出[SUMMER,FALL,WINTER]
  28.         System.out.println(es4);
  29.         //新创建的EnumSet集合的元素和es4集合的元素有相同类型,
  30.         //es5的集合元素 + es4集合元素 = Season枚举类的全部枚举值
  31.         EnumSet es5 = EnumSet.complementOf(es4); 
  32.         //输出[SPRING]
  33.         System.out.println(es5);
  34.     }
  35. }

注意以上的集合都不线程安全,解决线程问题,我将过两天总结。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值