java 集合框架

本文为集合框架总的整理,方便以后快速查看,大部分为链接指引(别人写的好,自己则没必要写了),有一些是看别人博客觉得看不懂(一上来就灌输一大堆概念)不够友好而自己写的。

-------------------------------------------------------------------------------------------------------------------------------------

1.ArrayListhttps://www.cnblogs.com/leesf456/p/5308358.html

2.LinkedListhttps://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 }
View Code

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 }
View Code
运行结果

向下类型转换时产生错误,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 }
View Code

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 }
View Code

(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 }
View Code

(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 }
View Code
 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 }
View Code

------------------------------------------------------------------------

 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 }
View Code

再创建一个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 }
View Code

创建一个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 }
View Code

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     }
View Code

 ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

7.集合体系框架总结

原文地址:https://www.cnblogs.com/bfcs/p/10383354.html