码迷,mamicode.com
首页 > 编程语言 > 详细

java基础——集合

时间:2015-06-12 20:56:52      阅读:198      评论:0      收藏:0      [点我收藏+]

标签:

集合与数组的区别:

 1.数组是固定长度的;集合的长度是可变的。

 2.数组可以存储基本数据类型,也可以存储引用数据类型;集合只能存储引用数据类型。

 3.数组存储元素必须是同一个数据类型;集合存储的对象可以是不同数据类型。

 java集合主要有3种重要的类型:

 ●List:是一个有序集合,可以存放重复的数据。

 ●Set: 是一个无序集合,不允许存放重复的数据。  

 ●Map: 是一个无序集合,集合中包含一个键对象和一个值对象,  键对象不允许重复,值对象可以重复。

 

下面是集合继承结构图-Collection部分,从图中可以很清楚的知道Collection接口下的子接口与实现类的关系。

技术分享

 Collection集合的常用方法:

 boolean add(Object o): 向集合中添加元素

 boolean addAll(Collection c):把集合c中的元素添加到指定的集合中

 void clear():清空集合

 boolean isEmpty(): 判断集合中是否有元素

 Iterator iterator(): 获取集合所依赖的迭代器对象

 boolean contains(Object o): 判断集合中是否包含某个元素

 boolean remove(Object o): 删除集合中某个元素

 int size(): 获取集合中元素的个数

 Object[] toArray(): 将集合转换成数组

 

技术分享
 1 import java.util.*;
 2 
 3 public class CollectionDemo {
 4     public static void main(String[] args) {
 5 
 6         // 创建集合
 7         Collection c = new ArrayList();// 多态
 8 
 9         // 添加元素
10         c.add(100); // 自动装箱
11         c.add("Java编程");
12 
13         Person p = new Person("Bill", 21);
14         c.add(p);// Collection集合只能单个存储元素,并且只能存储引用类型
15 
16         // 获取元素个数
17         System.out.println(c.isEmpty());// false 说明集合c不为空
18         System.out.println("c集合的元素个数为:" + c.size());// 个数为3
19 
20         // 将集合转换成Object类型的数组
21         Object[] obj = c.toArray();
22         for (int i = 0; i < obj.length; i++) {
23 
24             // 输出结果:100 Java编程 Person[name=Bill,age=21]
25             System.out.println(obj[i]);
26         }
27 
28         // 删除指定元素
29         c.remove(100); // 元素100已删
30         System.out.println("c集合的元素个数为:" + c.size());// 个数为2
31 
32         // 清空
33         c.clear();
34         System.out.println(c.isEmpty());// true 说明集合c为空
35         System.out.println("c集合的元素个数为:" + c.size());// 个数为0
36 
37     }
38 }
39 
40 class Person {
41     String name;
42     int age;
43 
44     Person(String name, int age) {
45         this.name = name;
46         this.age = age;
47     }
48 
49     // 重写Object中的toString方法
50     public String toString() {
51         return "Person[name=" + name + ",age=" + age + "]";
52     }
53 
54 }
View Code

 

Iterator iterator();获取集合所依赖的迭代器对象

 通过迭代器中的方法完成集合的迭代(遍历)

 这种方式是所有集合通用的遍历方式  

Itertor接口定义的三个方法:

 boolean hasNext():如果仍有元素可以迭代,则返回 true。

 Object next(): 返回迭代的下一个元素。

 void remove(): 从迭代器指向的 collection 中移除迭代器返回的最后一个元素(可选操作)。

 Iterator必须依附于Collection对象,若有一个Iterator对象,则必然有一个与之关联的Collection对象。

当使用Iterator对集合元素进行迭代时,Iterator并不是把集合元素本身传给迭代变量,而是把集合元素的值传给迭代变量,因此当修改迭代变量的值时对集合元素本身没有任何影响  

注意:  当使用Iterator迭代访问Collection集合元素时,Collection集合里的元素不能被改变,只能通过Iterator的remove方法删除上一次next方法返回的集合元素,否则将会引发 java.util.CencurrentModificationException异常。

 

技术分享
 1 import java.util.*;
 2 public class IteratorDemo {
 3 
 4     public static void main(String[] args) {
 5 
 6         // 创建一个集合
 7         Collection books = new HashSet();
 8         books.add("三国演义");
 9         books.add("西游记");
10         books.add("水浒传");
11 
12         // 获取books集合对应的迭代器
13         Iterator it = books.iterator();
14         while (it.hasNext()) {
15             // it.next()方法返回的是Object类型,需强制类型转换
16             String str = (String) it.next();
17             System.out.println(str);
18 
19             if (str.equals("三国演义")) {
20                 // 从集合中删除上一次next方法返回的元素
21                 it.remove();// 通过迭代器删除
22 
23                 // 不要使用集合自身所带的remove方法,会引发异常
24                 // books.remove(str);
25             }
26             // 对str变量赋值,不会改变集合元素本身
27             str = "红楼梦";// 此处代码对集合没有任何影响
28         }
29         System.out.println(books);// [西游记, 水浒传]
30     }
31 }
View Code

 

boolean contains(Object o):判断集合中是否包含某个元素
存储在集合中的元素应该重写equals方法

技术分享
 1 import java.util.*;
 2 public class ContainsDemo {
 3 
 4     public static void main(String[] args) {
 5 
 6         // 创建集合
 7         Collection c = new ArrayList();
 8 
 9         // 创建Integer类型对象
10         Integer i1 = new Integer(100);
11 
12         // 添加元素
13         c.add(i1);
14 
15         // 判断集合中是否包含i1
16         System.out.println(c.contains(i1));// true
17 
18         // 创建另一个Integer类型对象
19         Integer i2 = new Integer(100);
20         // contains方法底层调用的是equals方法。Integer重写了equals方法,i1就是i2
21         System.out.println(c.contains(i2));// true
22 
23         // 创建一个Student对象
24         Student s1 = new Student(100, "Bill");
25         // 添加到集合里
26         c.add(s1);
27         // 判断集合c中是否包含s1
28         System.out.println(c.contains(s1));// true
29 
30         // 创建另一个Student对象
31         Student s2 = new Student(100, "Bill");
32         // 重写equals方法之前,比较的是内存
33         // System.out.println(c.contains(s2));//false
34 
35         // 重写equals方法之后,比较的是内容
36         System.out.println(c.contains(s2));// true
37     }
38 }
39 
40 class Student {
41     int no;
42     String name;
43 
44     Student(int no, String name) {
45         this.no = no;
46         this.name = name;
47     }
48 
49     // 重写equals方法
50     // 要求:编号和姓名相同则表示同一个Student
51     public boolean equals(Object o) {
52         if (this == o) {
53             return true;
54         }
55         if (o instanceof Student) {
56             Student s = (Student) o;
57             if (s.no == this.no && s.name == this.name) {
58                 return true;
59             }
60         }
61         return false;
62     }
63 }
View Code

List集合

 ArrayList集合底层是数组。数组是有下标的.  所以ArrayList集合有很多自己的特性.

 ArrayList集合底层默认初始化容量是 10. 扩大之后的容量是原容量的1.5倍.

 Vector集合底层默认初始化容量也是10.扩大之后的容量是原容量的2倍.

 如何优化ArrayList和Vector?  

尽量减少扩容操作,因为扩容需要数组拷贝。数组拷贝很耗内存。一般推荐在创建集合的时候指定初始化容量。

技术分享
 1 import java.util.*;
 2 public class ListDemo {
 3 
 4     public static void main(String[] args) {
 5 
 6         // 创建List集合
 7         List li = new ArrayList();
 8         // List li = new LinkedList();
 9 
10         // 添加元素
11         li.add(100);
12         li.add(200);
13         li.add(400);
14 
15         // 在下标为2的位置上添加300
16         li.add(2, 300);
17 
18         // 取得第一个元素
19         System.out.println(li.get(0));// 100
20 
21         // 遍历(List集合特有的遍历方式)
22         for (int i = 0; i < li.size(); i++) {
23             Object o = li.get(i);
24             System.out.println(o);
25         }
26 
27         // 迭代器也可以
28         Iterator it = li.iterator();
29         while (it.hasNext()) {
30             System.out.println(it.next());
31         }
32     }
33 }
View Code

Set集合:HashSet

 1.HashSet底层实际上是一个HashMap,HashMap底层采用了哈希表数据结构。

 2.哈希表又叫做散列表,哈希表底层是一个数组,这个数组中每一个元素是一个单向链表。每个单向链表都有一个独一无二的hash值,代表数组的下标。在某个单向链表中的每一个节点上的hash值是相等的。hash值实际上是key调用hashCode方法,在通过"hash function"转换成的值。

 3.如何向哈希表中添加元素:先调用被存储的key的hashCode方法,经过某个算法得出hash值,如果在这个哈希表中不存在这个 hash值,则直接加入元素。如果该hash值已经存在,继续调用key之间的equals方法,如果equals方法返回false,则将该元素添加。如果equals方法返回true,则放弃添加该元素。

 4.HashSet其实是HashMap中的key部分。HashSet有什么特点,HashMap中的key 应该具有相同的特点。

 5.HashMap和HashSet初始化容量都是 16,默认加载因子是0.75,即当存储容量达到75%时就扩容。

 6.关于往Set集合中存储的元素,该元素的hashCode和equals方法:

 HashMap中有一个put方法,put(key,value) key是无序不可重复的.

 结论:存储在HashSet集合或者HashMap集合key部分的元素,需要同时重写hashCode+equals

技术分享
 1 import java.util.*;
 2 public class SetDemo {
 3 
 4     public static void main(String[] args) {
 5         
 6         // Set集合存储元素是无序不可重复的,这里就不做测试了
 7         
 8         //创建集合
 9         Set s = new HashSet();
10         
11         //这里假设键值重复只为做测试,实际上是不可重复的
12         Employee e1 = new Employee("1000","JACK");
13         Employee e2 = new Employee("1000","JACK");
14         Employee e3 = new Employee("1000","SCOTT");
15         Employee e4 = new Employee("2001","SUN");
16         Employee e5 = new Employee("3000","JIM");
17         Employee e6 = new Employee("3001","COOK");
18         
19         System.out.println(e1.hashCode());//重写hashCode方法后e1就是e2
20         System.out.println(e2.hashCode());
21         
22         //添加元素
23         s.add(e1);
24         s.add(e2);
25         s.add(e3);
26         s.add(e4);
27         s.add(e5);
28         s.add(e6);
29         
30         //查看集合元素个数
31         System.out.println(s.size()); //5
32         
33     }
34 }
35 
36 //假设该公司员工编号是: 1000 - 9999
37 class Employee{
38     
39     //编号
40     String no;
41     
42     //姓名
43     String name;
44     
45     //Constructor
46     Employee(String no,String name){
47         this.no = no;
48         this.name = name;
49     }
50     
51     //重写equals方法.
52     //如果员工编号相同,并且名字相同,则是同一个对象
53     public boolean equals(Object o){
54         if(this==o){
55             return true;
56         }
57         if(o instanceof Employee){
58             Employee e = (Employee)o;
59             if(e.no.equals(this.no) && e.name.equals(this.name)){
60                 return true;
61             }
62         }
63         
64         return false;
65     }
66     
67     //重写hashCode方法.
68     public int hashCode(){
69         //以员工编号分组.
70         return no.hashCode();
71     }
72 }
View Code

 

先对SortedSet做测试

技术分享
 1 import java.text.*;
 2 import java.util.*;
 3 
 4 public class SortedSetDemo01 {
 5 
 6     public static void main(String[] args) throws Exception {
 7 
 8         // 创建集合
 9         SortedSet ss = new TreeSet();
10 
11         // 测试Integer类型
12         ss.add(10); // 自动装箱
13         ss.add(20);
14         ss.add(15);
15         ss.add(30);
16         ss.add(25);
17         ss.add(9);
18 
19         // 遍历
20         Iterator it = ss.iterator();
21         while (it.hasNext()) {
22             Object element = it.next();
23             System.out.println(element);//9 10 15 20 25 30
24         }
25 
26         // 测试String类型
27         SortedSet strs = new TreeSet();
28 
29         strs.add("JACK");
30         strs.add("SUN");
31         strs.add("KOOK");
32         strs.add("LUCY");
33         strs.add("KING");
34 
35         // 遍历
36         it = strs.iterator();
37         while (it.hasNext()) {
38             Object element = it.next();
39             System.out.println(element);
40             /*输出:JACK
41                   KING
42                   KOOK
43                   LUCY
44                   SUN*/
45         }
46 
47         // 测试日期Date类型
48         String st1 = "2008-08-08";
49         String st2 = "2009-08-08";
50         String st3 = "2008-09-08";
51         String st4 = "2008-08-09";
52         String st5 = "2012-08-08";
53 
54         SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
55 
56         Date t1 = sdf.parse(st1);
57         Date t2 = sdf.parse(st2);
58         Date t3 = sdf.parse(st3);
59         Date t4 = sdf.parse(st4);
60         Date t5 = sdf.parse(st5);
61 
62         // 添加
63         SortedSet times = new TreeSet();
64 
65         times.add(t5);
66         times.add(t2);
67         times.add(t3);
68         times.add(t4);
69         times.add(t1);
70 
71         // 遍历
72         it = times.iterator();
73         while (it.hasNext()) {
74             Object element = it.next();
75             if (element instanceof Date) {
76                 Date d = (Date) element;
77                 
78                 System.out.println(sdf.format(d));
79                 /*输出:2008-08-08
80                         2008-08-09
81                       2008-09-08
82                       2009-08-08
83                       2012-08-08*/
84             }
85         }
86     }
87 }
View Code

SortedSet集合存储元素为什么可以自动排序?
  因为被存储的元素实现了Comparable接口,
      SUN编写TreeSet集合在添加元素的时候,会调用compareTo方法完成比较.

技术分享
 1 import java.util.*;
 2 
 3 public class SortedSetDemo02 {
 4 
 5     public static void main(String[] args) {
 6 
 7         SortedSet users = new TreeSet();
 8 
 9         User u1 = new User(15);
10         User u2 = new User(16);
11         User u3 = new User(25);
12         User u4 = new User(13);
13         User u5 = new User(11);
14 
15         // 添加元素
16         users.add(u1);
17         users.add(u2);
18         users.add(u3);
19         users.add(u4);
20         users.add(u5);
21 
22         // 遍历
23         Iterator it = users.iterator();
24         while (it.hasNext()) {
25             //输出:User[age=11] User[age=13] User[age=15] User[age=16] User[age=25]
26             System.out.println(it.next());
27         }
28     }
29 
30 }
31 
32 // 这是第一种方式.
33 class User implements Comparable {
34 
35     int age;
36 
37     User(int age) {
38         this.age = age;
39     }
40 
41     public String toString() {
42         return "User[age=" + age + "]";
43     }
44 
45     // 实现java.lang.Comparable;接口中的compareTo方法
46     // 该方法程序员负责实现,SUN提供的程序已经调用了该方法.
47     // 需求:按照User的age排序
48     public int compareTo(Object o) {
49         // 编写一个比较规则.
50         int age1 = this.age;
51         int age2 = ((User) o).age;
52         return age1 - age2;
53     }
54 }
View Code

让SortedSet集合做到排序还有另一种方式:java.util.Comparator;

单独编写一个比较器.

技术分享
 1 import java.util.*;
 2 
 3 public class SortedSetDemo03 {
 4 
 5     public static void main(String[] args) {
 6 
 7         // 创建TreeSet集合的时候提供一个比较器.
 8         SortedSet products = new TreeSet(new ProductComparator());
 9 
10         // 匿名内部类:不推荐使用,因为比较器无法得到重复利用。
11         /*
12          * SortedSet products = new TreeSet(new Comparator() { // 需求:按照商品价格排序
13          * public int compare(Object o1, Object o2) {
14          * 
15          * double price1 = ((Product) o1).price; double price2 = ((Product)
16          * o2).price;
17          * 
18          * if (price1 == price2) { return 0; } else if (price1 > price2) {
19          * return 1; } else { return -1; } } });
20          */
21 
22         Product p1 = new Product(3.4);
23         Product p2 = new Product(4.0);
24         Product p3 = new Product(3.0);
25         Product p4 = new Product(2.0);
26         Product p5 = new Product(5.0);
27 
28         // 添加元素
29         products.add(p1);
30         products.add(p2);
31         products.add(p3);
32         products.add(p4);
33         products.add(p5);
34 
35         // 遍历
36         Iterator it = products.iterator();
37         while (it.hasNext()) {
38             //输出2.0 3.0 3.4 4.0 5.0
39             System.out.println(it.next());
40             
41         }
42     }
43 
44 }
45 
46 class Product {
47 
48     double price;
49 
50     Product(double price) {
51         this.price = price;
52     }
53 
54     public String toString() {
55         return price + "";
56     }
57 
58 }
59 
60 // 第二种方法单独编写一个比较器
61 
62 class ProductComparator implements Comparator {
63 
64     // 需求:按照商品价格排序
65     public int compare(Object o1, Object o2) {
66 
67         double price1 = ((Product) o1).price;
68         double price2 = ((Product) o2).price;
69 
70         if (price1 == price2) {
71             return 0;
72         } else if (price1 > price2) {
73             return 1;
74         } else {
75             return -1;
76         }
77     }
78 
79 }
View Code

 

下面是集合继承结构图-Map部分,从图中可以清楚的知道Map接口下子接口与实现类的关系。

技术分享

关于Map集合中常用的方法


 void clear(); 清空Map
 boolean isEmpty();判断该集合是否为空
 int size(); 获取Map中键值对的个数。
 
 Object put(Object key, Object value); 向集合中添加键值对
 Object get(Object key);通过key获取value
 
  boolean containsKey(Object key); 判断Map中是否包含这样的key
  boolean containsValue(Object value); 判断Map中是否包含这样的value
  
  Object remove(Object key); 通过key将键值对删除.
  
  Collection values(); 获取Map集合中所有的value
  
  Set keySet(); 获取Map中所有的key
  
  Set entrySet();返回此映射中包含的映射关系的 Set 视图。

  注意:存储在Map集合key部分的元素需要同时重写hashCode+equals方法.

技术分享
 1 import java.util.*;
 2 
 3 public class MapDemo01{
 4     
 5     public static void main(String[] args){
 6         
 7         //1.创建Map集合
 8         Map persons = new HashMap(); //HashMap的默认初始化容量是16,默认加载因子是0.75
 9         
10         //2.存储键值对
11         persons.put("10000","JACK");
12         persons.put("10011","JACK");
13         persons.put("10002","SUN");
14         persons.put("10003","COOK");
15         persons.put("10004","KING");
16         persons.put("10000","LUCY");
17         
18         //3.判断键值对的个数
19         //Map中的key是无序不可重复的.和HashSet相同.
20         System.out.println(persons.size());//5
21         
22         //4.判断集合中是否包含这样的key
23         System.out.println(persons.containsKey("10000")); //true
24         
25         //5.判断集合中是否包含这样的value
26         //注意:Map中如果key重复了,value采用的是“覆盖”。
27         System.out.println(persons.containsValue("LUCY")); //true
28         
29         //6.通过key获取value
30         String k = "10002";
31         Object v = persons.get(k);
32         System.out.println(v); //SUN
33         
34         //7.通过key删除键值对
35         persons.remove("10002");
36         System.out.println(persons.size()); //4
37         
38         //8.获取所有的value
39         Collection values = persons.values();
40         Iterator it = values.iterator();
41         while(it.hasNext()){
42             System.out.println(it.next()); 
43             /*LUCY
44               JACK
45               COOK
46               KING*/
47         }
48         
49         //9.获取所有的key
50         //以下程序演示如何遍历Map集合.
51         Set keys = persons.keySet();
52         
53         Iterator it2 = keys.iterator();
54         
55         while(it2.hasNext()){
56             Object id = it2.next();
57             Object name = persons.get(id);
58             System.out.println(id+"-->"+name);
59             /*10000-->LUCY
60             10011-->JACK
61             10003-->COOK
62             10004-->KING*/
63 
64         }
65         
66         //10.entrySet
67         //将Map转换成Set集合.
68         /*
69         Set entrySet = persons.entrySet();
70         Iterator it3 = entrySet.iterator();
71         while(it3.hasNext()){
72             System.out.println(it3.next());
73         }
74         */
75         
76     }
77 }
View Code

 

使用集合的技巧:

看到Array就是数组结构,有角标,查询速度很快。

看到link就是链表结构:增删速度快,而且有特有方法。addFirst; addLast; removeFirst(); removeLast(); getFirst();getLast();

看到hash就是哈希表,就要想要哈希值,就要想到唯一性,就要想到存入到该结构的中的元素必须覆盖hashCode,equals方法。

看到tree就是二叉树,就要想到排序,就想要用到比较。

比较的两种方式:

一个是Comparable:覆盖compareTo方法;

一个是Comparator:覆盖compare方法。

LinkedHashSet,LinkedHashMap:这两个集合可以保证哈希表有存入顺序和取出顺序一致,保证哈希表有序。

 

   这是我在自学到java集合时通过看视频所整理出来的一部分内容,马马虎虎。在此感谢授课老师将视频分享,让在黑暗中摸索的我看到了一丝光明。把自己学到的一些知识分享出来是快乐的,这样也能鞭策自己,磨砺自己。所谓当局者迷,旁观者清,在此还望各位前辈不吝赐教,指出不足之处,这样我也才能更好的认清自己。下面附上我所看视频的下载地址:http://pan.baidu.com/s/1i342Y6x

java基础——集合

标签:

原文地址:http://www.cnblogs.com/zhimu/p/4563205.html

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