本文为集合框架总的整理,方便以后快速查看,大部分为链接指引(别人写的好,自己则没必要写了),有一些是看别人博客觉得看不懂(一上来就灌输一大堆概念)不够友好而自己写的。
-------------------------------------------------------------------------------------------------------------------------------------
1.ArrayList:https://www.cnblogs.com/leesf456/p/5308358.html
2.LinkedList:https://www.cnblogs.com/leesf456/p/5308843.html
3.Vector:用法--->https://www.cnblogs.com/zheting/p/7708366.html 源码解析------>https://www.cnblogs.com/skywang12345/p/3308833.html
和ArrayList的区别---->https://www.cnblogs.com/wanlipeng/archive/2010/10/21/1857791.html
-------------------------------------------------------------------------------------------------------------------------------------------------------
4.Map
1). 实现 Map 接口的类用来存储键(key) -值(value)对
2). Map 接口的实现类有 HashMap 和 TreeMap 等
3). Map 类中存储的键-值对通过键来标识,所以键值不能
重复
4.1HashMap的使用
1 import java.util.Collection; 2 import java.util.HashMap; 3 import java.util.Set; 4 5 public class TestHashMap { 6 public static void main(String[] args) { 7 //Map接口的特点,key不允许重复,值可以重复,而且key是无序的 8 //创建集合对象 9 HashMap hm=new HashMap(); 10 //(1)添加元素 11 hm.put("hello", 123);//123自动装箱,Integer类型 12 hm.put("world",456); 13 hm.put("hello", 1000); //集合中的key不能重复,如果重复,将进行值的覆盖 14 hm.put("java", 1000); 15 System.out.println("集合中元素的个数:"+hm.size());//3 16 System.out.println("集合是否为空:"+hm.isEmpty());//false 17 System.out.println(hm);//{world=456, java=1000, hello=1000} 18 System.out.println(hm.remove("world"));//456 (先输出后移除) 19 System.out.println(hm);//{java=1000, hello=1000} 20 //判断 21 System.out.println(hm.containsKey("java")+" "+hm.containsKey("world"));//true false 22 System.out.println(hm.containsValue(1000)+" "+hm.containsValue(2000));//true false 23 //获取元素 24 System.out.println(hm.get("java")+" "+hm.get("world"));//1000 null 25 //获取所有key的集合 26 Set set=hm.keySet(); 27 for(Object obj:set){ //java 28 System.out.println(obj);//hello 29 } 30 //获取所有的value的集合 31 System.out.println(" --------------------------"); 32 Collection coll=hm.values(); 33 for(Object obj:coll){ //1000 34 System.out.println(obj);//1000 35 } 36 //获取所有key-value关系的集合 37 Set entrySet=hm.entrySet(); 38 for(Object obj:entrySet){ //java=1000 39 System.out.println(obj);//hello=1000 40 } 41 42 /** 43 * HashMap与Hashtable用法相同 44 * HashMap与Hashtable的区别 45 * (1)版本不同 HashMap JDK1.2 Hashtable 1.0 46 * (2)HashMap继承了AbstractMap,实现了Map接口,Hashtable继承了Dictionary实现Map接口 47 * (3)HashMap允许null值和null键, 但是null作为key只允一个, Hashtable非null的键和值 48 * (4)HashMap是线程不同步的 (效率高,安全性低),Hashtable(效率低,安全性高)线程同步 49 * 50 * 51 * */ 52 } 53 }
4.2HashMap实现原理---->https://www.cnblogs.com/xwdreamer/archive/2012/05/14/2499339.html
4.3二叉树和红黑树----->https://www.cnblogs.com/guweiwei/p/7080971.html 深入理解--->http://www.cnblogs.com/yangecnu/p/Introduce-Red-Black-Tree.html
4.4TreeMap--->Key:唯 一,有序,升序
如果使用 TreeMap 存储自定义对象做为 key 时,要求必须具
备比较规则,否则运行报错
浅析--->https://www.cnblogs.com/yueyanglou/p/5283915.html 深入理解--->https://www.cnblogs.com/skywang12345/p/3310928.html
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
5.Set:唯一、无序
Set的实现类都是基于Map来实现的(HashSet是通过HashMap实现的,TreeSet是通过TreeMap实现的)。
HashSet依赖于HashMap,它实际上是通过HashMap实现的。HashSet中的元素是无序的。
HashSet------->https://www.cnblogs.com/skywang12345/p/3311252.html
TreeSet依赖于TreeMap,它实际上是通过TreeMap实现的。TreeSet中的元素是有序的。
TreeSet-------->https://www.cnblogs.com/skywang12345/p/3311268.html
--------------------------------------------------------------------------------------------------------------------------------------------------------------
6.泛型
6.1 为什么需要使用泛型
JDK1.4 以前类型不明确:
装入集合的类型都被当作 Object 对待,从而失去自己的实际
类型。
从集合中取出时往往需要转型,效率低,容易产生错误。
1 import java.util.ArrayList; 2 3 public class Test { 4 public static void main(String[] args) { 5 6 ArrayList a1 = new ArrayList(); 7 a1.add("hello"); 8 a1.add(123); 9 for(Object obj : a1) { 10 String s = (String)obj; 11 System.out.println(s); 12 } 13 } 14 }
向下类型转换时产生错误,Integer是不能去转成String的
---------------------------------------------------------------------------------------------------------------
6.2 解决办法:
泛型,在定义集合的时候同时定义集合中对象的类型
1 import java.util.ArrayList; 2 3 public class Test { 4 public static void main(String[] args) { 5 //在创建集合对象时,明确集合中所存储的元素的类型 6 7 ArrayList<String> al=new ArrayList<String>(); 8 al.add("hello"); 9 //al.add(123);//指定为String存储类型后再添加Integer类型会报错 10 for (String str : al) { 11 System.out.println(str); 12 } 13 } 14 }
6.3 好处:
增强程序的可读性和安全性
6.4 泛型的分类
(1)泛型类
1 public class MyGeneric<T> {//T就是一个英文字母,代表一种数据类型,在创建实例时确定 2 3 } 4 class TestMyGeneric{ 5 public static void main(String[] args) { 6 MyGeneric<String> my1=new MyGeneric<String>(); 7 MyGeneric<Integer> my2=new MyGeneric<Integer>(); 8 } 9 }
(2)泛型接口
1 public interface MyInterface<T> { 2 3 } 4 class MyImplement implements MyInterface<String>{ 5 6 } 7 class MyImplement1<T> implements MyInterface<T>{ 8 9 } 10 class TestMyInterface{ 11 public static void main(String[] args) { 12 MyImplement my=new MyImplement(); 13 14 MyImplement1<Integer> my2=new MyImplement1<Integer>(); 15 } 16 }
(3)泛型方法
1 public class MyMethod<T> {//泛型类 2 public void show(T t){ //在创建MyMethod类的对象时决定 3 System.out.println(t); 4 } 5 public <Q> void method(Q q){ //在调用method这个方法时明确 6 System.out.println(q); 7 } 8 public <K>void fun(K...k){ //可变参数的泛型方法 9 for (int i = 0; i < k.length; i++) { 10 System.out.println(k[i]); 11 } 12 } 13 }
1 public class TestMyMethod { 2 public static void main(String[] args) { 3 MyMethod<String> my=new MyMethod<String>(); 4 my.show("hello");//在创建类的对象时明确了数据类型为String 5 6 //有了泛型方法,解决了参数个数相同的情况下的方法重载 7 my.method("hello"); 8 my.method(123); 9 my.method('a'); 10 11 //可变参数的泛型方法,解决参数的个数不同,类型不同的方法重载 12 my.fun("hello"); 13 my.fun("hello","world","java"); 14 my.fun(123,456); 15 } 16 }
------------------------------------------------------------------------
6.5 泛型的高级使用
泛型的上限:使用关键字 extends,表示参数化的类型可能是
所指定的类型或者是此类型的子类
泛型的下限:使用关键字 super 进行声明,表示参数化的类型
可能是所指定的类型,或者是此类型的父类型,直至 Object
类
先创建一个Person类,包含姓名,年龄属性,get() set()方法,有参无参构造函数,重写toString方法
1 public class Person{ 2 private String name; //姓名 3 private int age;//年龄 4 5 @Override 6 public String toString() { 7 return "Person [name=" + name + ", age=" + age + "]"; 8 } 9 public String getName() { 10 return name; 11 } 12 public void setName(String name) { 13 this.name = name; 14 } 15 public int getAge() { 16 return age; 17 } 18 public void setAge(int age) { 19 this.age = age; 20 } 21 public Person(String name, int age) { 22 super(); 23 this.name = name; 24 this.age = age; 25 } 26 public Person() { 27 super(); 28 } 29 }
再创建一个Student类,继承Person类,包含学号属性,get() set()方法,有参无参构造函数,重写toString方法
1 public class Student extends Person { 2 private String stuNo;//学号 3 4 @Override 5 public String toString() { 6 return super.toString()+"Student [stuNo=" + stuNo + "]"; 7 } 8 9 public String getStuNo() { 10 return stuNo; 11 } 12 public void setStuNo(String stuNo) { 13 this.stuNo = stuNo; 14 } 15 public Student(String name, int age, String stuNo) { 16 super(name, age); 17 this.stuNo = stuNo; 18 } 19 public Student() { 20 super(); 21 } 22 }
创建一个Test类测试
1 import java.util.ArrayList; 2 3 public class Test { 4 public static void main(String[] args) { 5 //创建集合对象,同时明确了集合中所存储的对象的类型只能是Person类型 6 ArrayList<Person> al=new ArrayList<Person>(); 7 //创建Person类型的对象添加到集合中 8 Person p1=new Person("marry", 20); 9 Person p2=new Person("lili",29); 10 Person p3=new Person("jack",18); 11 //添加以集合中 12 al.add(p1); 13 al.add(p2); 14 al.add(p3); 15 //遍历集合 16 print(al); 17 /* Person [name=marry, age=20] 18 Person [name=lili, age=29] 19 Person [name=jack, age=18] 20 * */ 21 22 23 //创建一个集合对象,用于存储Student类型的对象 24 ArrayList<Student> al2=new ArrayList<Student>(); 25 Student stu1=new Student("sean", 20, "sxt1001"); 26 Student stu2=new Student("nico",19,"sxt1002"); 27 //添加到集合中 28 al2.add(stu1); 29 al2.add(stu2); 30 //需要遍历集合 31 print(al2); 32 /* 33 * Person [name=sean, age=20]Student [stuNo=sxt1001] 34 Person [name=nico, age=19]Student [stuNo=sxt1002] 35 */ 36 37 38 //调用show方法 39 System.out.println(" --------------------------- "); 40 41 show(al); 42 /* 43 * Person [name=marry, age=20] 44 Person [name=lili, age=29] 45 Person [name=jack, age=18] 46 */ 47 48 show(al2); 49 /* 50 * Person [name=sean, age=20]Student [stuNo=sxt1001] 51 Person [name=nico, age=19]Student [stuNo=sxt1002] 52 */ 53 54 ArrayList<Object> alObject=new ArrayList<Object>(); 55 Object ob1=new Object(); 56 Object obj2=new Object(); 57 alObject.add(ob1); 58 alObject.add(obj2); 59 60 show(alObject);//泛型下限 Object类型也可以使用show()方法 61 /* 62 * java.lang.Object@1175e2db 63 java.lang.Object@36aa7bc2 64 */ 65 } 66 67 //泛型上限,Person及Person的子类 68 //<? extends Person>解释:?(通配符) 谁 extends 继承了 Person 谁就可以使用这个方法 69 public static void print(ArrayList<? extends Person> al){ 70 for (Person p : al) { 71 System.out.println(p); 72 } 73 } 74 75 //泛型下限,Student及Student的父类 76 //<? super Student>解释: ?(通配符) 谁 super Student 是Student的父类 谁就可以使用这个方法 77 public static void show(ArrayList<? super Student> al){ 78 for (Object obj : al) { 79 System.out.println(obj); 80 } 81 } 82 }
6.6 泛型的好处
类型安全。 泛型的主要目标是提高 Java 程序的类型安全。通过知道使用泛型定义的变量的类型限制,编译器可以在一个高得多的程度上验证类型假设。没有泛型,这些假设就只存在于程序员的头脑中(或者如果幸运的话,还存在于代码注释中)。
消除强制类型转换。 泛型的一个附带好处是,消除源代码中的许多强制类型转换。这使得代码更加可读,并且减少了出错机会。
尽管减少强制类型转换可以降低使用泛型类的代码的罗嗦程度,但是声明泛型变量会带来相应的罗嗦。比较下面两个代码例子。
该代码不使用泛型:
List li = new ArrayList(); li.put(new Integer(3)); Integer i = (Integer) li.get(0);
该代码使用泛型:
List<Integer> li = new ArrayList<Integer>(); li.put(new Integer(3)); Integer i = li.get(0);
在简单的程序中使用一次泛型变量不会降低罗嗦程度。但是对于多次使用泛型变量的大型程序来说,则可以累积起来降低罗嗦程度。
6.7 容器中使用泛型
1 import java.util.ArrayList; 2 import java.util.HashMap; 3 import java.util.HashSet; 4 import java.util.LinkedList; 5 import java.util.TreeMap; 6 import java.util.TreeSet; 7 8 public class Test2 { 9 public static void main(String[] args) { 10 11 ArrayList<String> al=new ArrayList<String>(); 12 al.add("hello"); 13 14 LinkedList<Integer> linkedList=new LinkedList<Integer>(); 15 linkedList.add(123);//123进行了自动装箱 16 17 //存储自定时对象时,要求Person类重写hashCode()及equals()方法 18 HashSet<Person> hs=new HashSet<Person>(); 19 20 //Person 对象具备比较规则 ,可以是内部比较器,也可以外部比较器 21 TreeSet<Person> treeSet=new TreeSet<Person>(); 22 23 HashMap<String,Integer> hm=new HashMap<String,Integer>(); 24 hm.put("hello", 123); 25 26 HashMap<Person,String> hm2=new HashMap<Person,String>(); 27 Person p1=new Person("marry",20); 28 hm2.put(p1, p1.getName()); 29 30 TreeMap<Person,Integer> tm=new TreeMap<Person,Integer>(); 31 tm.put(p1, p1.getAge()); 32 33 //泛型只在编译期间起作用 34 }
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
7.集合体系框架总结