黑马程序员——java基础——集合框架

 

 

1.Java Collection Framework 

JDK API 在 java.util包中专门设计了一组专门用来存储其他对象的类,这组类被称为对象容器类,简称容器类,这组类和接口的设计结构也被统称为集合框架.

 

2.JCF 接口介绍

Collection 接口:定义了存取对象的方法,每一具体的实现类,有两个非常常用的子接口

Set 接口:存放的元素不包含重复的集合接口。

List 接口:存放的元素有序且包含重复的集合接口。

说明:“元素”—对象,实例。

        “重复”—两个对象通过equals相等。

        “有序”—元素存入的顺序与取出的顺序相同。

Map 接口:定义了存储“键(key)值(vaule)映射对”的方法。

3.Collection 接口方法

 

 

 

 

4.Iterator 接口 

所实现了collection 接口的集合类都有一个iterator()方法用以返回一个实现了iterator接口的对象。

Iterator 对象称作迭代器,用以方便的实现对集合内元素的遍历操作。

Iterator 接口中定义了如下方法:

Boolean hashNext();  //判断游标右边是否有元素

Object next();       // 返回游标右边的元素并将游标移动到下一个位置

Void remove();      //  删除游标左面的元素

 

5.set 接口实现类

Set 接口没有提供collection 接口额外的方法,但实现set 接口的集合类中的元素是不可重复的。

Set 集合与数学中的“集合”概念相对应。

JDK API中所提供的set 集合类常用的有:

Hashset :不保存元素的加入顺序。它是根据元素的 哈希码进行存放,所以取出元素时也可以根据哈希码快速找到。

示例:HashSetTest.java

 1 import java.util.HashSet;
 2 
 3 import java.util.Iterator;
 4 
 5  
 6 
 7  
 8 
 9 public class HashSetTest {
10 
11 public static void main (String[] args){
12 
13 HashSet hs = new HashSet();
14 
15 hs.add("张三");
16 
17 hs.add("李四");
18 
19 hs.add("王五");
20 
21 hs.add("赵六");
22 
23   hs.add("赵六");
24 
25 System.out.println(hs.size())
26 
27 //迭代器
28 
29 Iterator it = hs.iterator();
30 
31 while(it.hasNext()){
32 
33 //显示每个放进去的元素
34 
35 System.out.println(it.next());
36 
37 }
38 
39 }
40 
41 }

 

  

 

执行结果:

 

 

1 5
2 
3 赵六
4 
5 张三
6 
7 李四
8 
9 王五

 

  

在此处,添加时虽然是添加了6个元素,但是其中有一个元素是重复的,所以hashset 自动没有去添加重复的元素。所以成功添加的元素依然是5个。

LinkedHashSet: 根据元素的哈希码进行存放,同时用链表记录元素的加入顺序。

示例: HashSetTest.java

 1 import java.util.Iterator;
 2 
 3 import java.util.LinkedHashSet;
 4 
 5  
 6 
 7  
 8 
 9 public class HashSetTest {
10 
11 public static void main(String[] args){
12 
13 LinkedHashSet<String> lhs = new LinkedHashSet<String>();
14 
15 lhs.add("张三");
16 
17 lhs.add("李四");
18 
19 lhs.add("王五");
20 
21 lhs.add("赵六");
22 
23 lhs.add("赵六");
24 
25 Iterator it = lhs.iterator();
26 
27 while(it.hasNext()){
28 
29 System.out.println(it.next());
30 
31 }

 

  

执行结果:

张三

李四

王五

赵六

可以看出来,linkedhashset 是不重复且有序的。Linkedhashset会比hashset 的效率低一些。

 

 

Treeset :使用红黑树结构对加入的元素进行排序存放。

放入treeset 中元素必须是可“排序”的注意:对加入的元素要实现compareto()方法要实现implements compareable接口。

 

6.List接口实现类

ArrayList类:支持可随需要而增长的动态数组。

示例:ListDemo.java

 1 import java.util.ArrayList;
 2 
 3 import java.util.Collection;
 4 
 5 import java.util.Iterator;
 6 
 7  
 8 
 9  
10 
11 public class ListDemo {
12 
13 public static void main(String[] args){
14 
15 //子类接口父类引用
16 
17 Collection c1 = new ArrayList();
18 
19 for(int i=0;i<10;i++){
20 
21 c1.add(new Integer(i));
22 
23 //循环10个整型的包装类对象
24 
25 }
26 
27 System.out.println("c1:"+c1);
28 
29 Collection c2 = new ArrayList();
30 
31 //将集合c1添加到c2 中去
32 
33 c2.addAll(c1);
34 
35 //删除
36 
37 c2.remove(new Integer(3));
38 
39 //添加
40 
41 c2.add("hehe");
42 
43 System.out.println("c2:"+c2);
44 
45 Iterator it = c2.iterator();
46 
47 //迭代器接口
48 
49 while(it.hasNext()){
50 
51 //迭代器迭代遍历
52 
53 System.out.println("iterator遍历c2" +
54 
55 it.next()+"\t" );
56 
57 }
58 
59 }

 

  

执行结果:

c1:[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

c2:[0, 1, 2, 4, 5, 6, 7, 8, 9, hehe]

iterator遍历c20

iterator遍历c21

iterator遍历c22

iterator遍历c24

iterator遍历c25

iterator遍历c26

iterator遍历c27

iterator遍历c28

iterator遍历c29

iterator遍历c2hehe

 

  

 

 

LinkedList 类:使用双向链表实现的容器,所以针对频繁的插入或删除元素使用LinkedList类效率较高。

示例:LinkedListDemo.java

import java.util.LinkedList;

 

 

public class LinkedListDemo {

 

/**

 * @param args

 */

public static void main(String[] args) {

// TODO Auto-generated method stub

LinkedList ll = new LinkedList();

ll.add("B");

ll.add("C");

ll.add("D");

ll.add("E");

ll.add("F");

System.out.println("初始的linkedlist内容:"+ll);

ll.addFirst("A");

//在第一行添加一个元素

ll.addLast("G");

//在最后一行添加一个元素

ll.add(1,"A1");

//在指定元素出添加元素

System.out.println("添加之后的linkedlist内容:"+ll);

ll.remove("F");

//删除F元素

ll.remove(2);

//删除第二个元素

ll.removeFirst();

//删除第一个元素

ll.removeLast();

//删除最后一个元素

System.out.println("删除之后的linkedlist内容:"+ll);

Object ob = ll.get(2);

//获取指定的元素

ll.set(2, ob+"changed");

//修改内容

System.out.println("修改之后的linkedlist内容:"+ll);

}

 

}

 

  

执行结果:

初始的linkedlist内容:[B, C, D, E, F]

添加之后的linkedlist内容:[A, A1, B, C, D, E, F, G]

删除之后的linkedlist内容:[A1, C, D, E]

修改之后的linkedlist内容:[A1, C, Dchanged, E]

 

Vector 类:提供的访问方法支持类似数组运算和与vector大小相关的运算。

7.Map接口

Map 实现类中存储的“键-值”映射对是通过键来唯一标识。Map 底层的“键”是用set 来存放的。

Hashmap实现类:基础哈希表的map 接口的实现,它是使用频率最高的一个容器,提供所有可选的映射操作, 它内部对“键”用set进行散列存放。所以根据“键”去取“值”的效率很高。并且它允许使用null值和null键,但它不保证映射的顺序。

示例:HashMapDemo.java

import java.util.*;

import java.util.Set;

 

 

public class HashMapDemo {

 

/**

 * @param args

 */

public static void main(String[] args) {

// TODO Auto-generated method stub

HashMap hashmap = new HashMap();

//存放值用put方法,记住所存的值一定是键值对

hashmap.put("0", "a");

hashmap.put("1", "b");

hashmap.put("2", "c");

hashmap.put("3", "d");

hashmap.put("4", "e");

System.out.println(hashmap);

//该容器有其内部的排序方式 事实上是依据哈希算法来排的

Set set = hashmap.keySet();

//获取全部键,返回值是set

Iterator it = (Iterator) set.iterator();

while(it.hasNext()){

System.out.print(hashmap.get(it.next())+";");

}

 

 

}

 

}

 

执行结果:

1 {3=d, 2=c, 1=b, 0=a, 4=e}
2 
3 d;c;b;a;e;

 

LinkedHashMaphashmap 的子类,它可以依照插入的顺序来排列元素增删改效率比较高。

TreeMap容器类:比较特殊,treemap内部使用红黑树结构对“key”进行排序存放,所以放入treemap中的“key-value”对的“key”必须是可“排序”的。

Properties类表示了一个持久的属性集。它可以保存在流中加载。属性列表中每个键及其对应值都是一个字符串。

 

8.集合类的选择

主要从存放要求和读写数据效率两方面考虑

存放要求:无序-set-不能重复

有序-list-允许重复

key-value”对-map

读写效率:

Hash*-两者都最高

Array*-读快写慢

Linked*-读慢写快

Tree*-加入元素可排序使用

9.Collections

Collections是一个工具类,用来对集合进行操作,它主要提供一些排序的算法包括随机排序,后向排序。

10.泛型

泛型:就是在定义的时候,指定义它为通用类型,也就是数据类型可以是任意的类型,具体调用的时候,要将通用类型转换成指定的类型来使用1

泛型的使用:

1、消除类型转换:TestGenerics1.java

 

import java.util.*;

public class TestGenerics1 {

public static void main(String[] args) {

List<String> l = new ArrayList<String>();

l.add("ABC");

l.add("DEF");

String str = l.get(0);// 使用泛型后,获得对象时不用进行强制类型转换

/*

 * 错误,试图将Integer和Double类型的对象放入指定存放String类型对象的 集合中 l.add(1); l.add(1.5);

 */

for (String s : l) {// for-each循环 (集合/数组中元素类型 变量:集合/数组名)

System.out.println(s);

}

Map<Integer, String> map = new HashMap<Integer, String>();

map.put(1, "Huxz");

map.put(2, "Liucy");

map.put(3, "TangLiang");

// map.put(1.5,"Liucy");

// map.put("Liucy",1.5);

Set<Integer> keys = map.keySet();

for (Integer i : keys) {

 

String value = map.get(i);

System.out.println(i + "---" + value);

}

List<Number> list = new ArrayList<Number>();

list.add(10);

list.add(1.5);

/*

 * List<Number> list2; List<Integer> list3=new ArrayList<Integer>();

 * list2=list3;

 */

}

}

 

 

2、自动解包装与自动包装的功能:TestGenerics2.java

 

  1 import java.util.*;
  2 
  3 import static java.lang.System.*;
  4 
  5  
  6 
  7 public class TestGenerics2 {
  8 
  9 public static void main(String[] args) {
 10 
 11 List<String> l1 = new ArrayList<String>();
 12 
 13 l1.add("中国");
 14 
 15 List<Object> l2 = new ArrayList<Object>();
 16 
 17 l2.add(88);
 18 
 19 List<Number> l3 = new ArrayList<Number>();
 20 
 21 l3.add(8.8);
 22 
 23 List<Integer> l4 = new ArrayList<Integer>();
 24 
 25 l4.add(99);
 26 
 27 List<Double> l5 = new ArrayList<Double>();
 28 
 29 l5.add(100.8);
 30 
 31 print(l1);   //String类型的泛型对象
 32 
 33 print(l2);   //Object类型的泛型对象
 34 
 35 print(l3);  //Number类型的泛型对象
 36 
 37 print(l4);  //Integer类型的泛型对象
 38 
 39 print(l5);  //Double类型的泛型对象
 40 
 41 }
 42 
 43  
 44 
 45 // 方法参数中使用集合时不指定泛型,默认为<?>
 46 
 47  public static void print(List list) {
 48 
 49 for (Object o : list) {
 50 
 51 System.out.println(o);
 52 
 53 }
 54 
 55 }
 56 
 57  
 58 
 59 /*
 60 
 61  * <?> 允许所有泛型的引用调用 
 62 
 63  * public static void print(List<?> list){ for(Object
 64 
 65  * o:list){ out.println(o); } }
 66 
 67  */
 68 
 69 /*
 70 
 71  * <? extends Number> 只允许泛型为 Number及Number子类的引用调用
 72 
 73  */
 74 
 75 //  public static void print(List<? extends Number> list) {
 76 
 77 // for (Number o : list) {
 78 
 79 // out.println(o);
 80 
 81 // }
 82 
 83 // }
 84 
 85 /*
 86 
 87  * <? extends Comparable> 只允许泛型为实现了Comparable接口的实现类的引用调用
 88 
 89 //  */
 90 
 91 //  public static void print(List<? extends Comparable> list) {
 92 
 93 // for (Comparable o : list) {
 94 
 95 // out.println(o);
 96 
 97 // }
 98 
 99 // }
100 
101 /*
102 
103  * <? super Number> 只允许泛型为Number及Number父类的引用调用
104 
105  */
106 
107 // public static void print(List<? super Number> list) {
108 
109 // for (Object o : list) {
110 
111 // out.println(o);
112 
113 // }
114 
115 // }
116 
117  
118 
119 /*
120 
121  * 方法参数中<? extends Number&Comparable>这种修饰符是不支持的
122 
123  */
124 
125 //  public static void
126 
127 //     print(List<? extends Number & Comparable> list){ 
128 
129 //   for(Object o:list){
130 
131 //        out.println(o);
132 
133 //     }
134 
135 //  }
136 
137 }

 

 

3、限制泛型中类型参数的范围:TestGenerics3.java

 

import java.util.*;

 

/*修饰符 泛型 返回类型 方法名 参数表 抛出的异常

 1.<T> 允许所有泛型的引用调用

 2.<T extends Number> 

 只允许泛型为Number及Number子类的引用调用

 3.<T extends Comparable> 

 只允许泛型为实现了Comparable接口的实现类的引用调用

 4.<T extends Number&Comparable>

 只允许泛型为既是Number及Number子类又实现了Comparable接口的实现类的引用调用

 * K —— 键,比如映射的键。 

* V —— 值,比如 List 和 Set 的内容,或者 Map 中的值。 

* E —— 异常类。 

* T —— 泛型

 

 类型参数 K 和 V 在类级别的规格说明,表示在声明一个 Map 类型的变量时指定的类型的占位符

 * */

public class TestGenerics3 {

 

List<?> list=null;

public static void main(String[] args) {

List<String> l1 = new ArrayList<String>();

List<Object> l2 = new ArrayList<Object>();

List<Number> l3 = new ArrayList<Number>();

List<Integer> l4 = new ArrayList<Integer>();

List<Double> l5 = new ArrayList<Double>();

String[] a1 = new String[10];

Object[] a2 = new Object[10];

Number[] a3 = new Number[10];

Integer[] a4 = new Integer[10];

Double[] a5 = new Double[10];

copyFromArray(l1, a1);

copyFromArray(l2, a2);

copyFromArray(l3, a3);

copyFromArray(l4, a4);

copyFromArray(l5, a5);

}

 

// 修饰符 泛型 返回类型 方法名 参数表 抛出的异常

 public static <T> void copyFromArray(List<T> l, T[] a) {

for (T o : a) {

l.add(o);

}

}

/*

 * <T extends Number> 只允许泛型为Number及Number子类的引用调用

 */

//  public static <T extends Number> void copyFromArray(List<T> l, T[] a) {

// for (T o : a) {

// l.add(o);

// }

// }

/*

 * 此处不许用super

 */

//  public static <T super Number> void copyFromArray(List<T> l,T[] a){

//  for(T o:a){

//  l.add(o);

//  }

//  }

 

 public static <T, V> void m(List<T> l1, List<V> l2) {

   /*T通用类型

   V通用值*/

 }

/*

 * <T extends Number&Comparable>只允许泛型为既是Number及Number子类又

 * 实现了Comparable接口的实现类的引用调用

 */

// public static <T extends Number & Comparable> void copyFromArray(List<T> l,T[] a) {

// for (T o : a) {

// l.add(o);

// }

// }

}

 

 

4、泛型方法:在方法的定义中添加一个泛型参数列表或一个泛型返回值类型,可以将 方法泛型化

5、泛型类:在类的定义中添加一个泛类参数列表,可以将类泛型化

 

posted @ 2015-11-06 12:51  年少不知青衫薄  阅读(104)  评论(0编辑  收藏  举报