-----------android培训、java培训、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;
LinkedHashMap是hashmap 的子类,它可以依照插入的顺序来排列元素增删改效率比较高。
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、泛型类:在类的定义中添加一个泛类参数列表,可以将类泛型化