目录结构:
1.1什么是集合
集合是对一组存储数据类的统称,相关的类都存放在java.util包中。
Collection:
Map:
图中灰底的类是比较常用的类,从上面的图片中我们可以看出,
集合分为两大类:Collection和Map
1.2 Collection和Map的区别
Collection接口中存放的是单个元素
Map接口存放的是单对元素
1.3 List和Set的区别
List接口是有序的,其中的元素可以重复
Set接口是无序的,其中的元素不可以重复
1.4 ArrayList和LinkedList的区别
ArrayList的底层实现是动态数组结构的,查找和修改元素方便,增加和删除元素不方便。
LinkedList的底层实现是链表结构,增加和删除元素方便,查找和修改元素不方便。
1.5 HashSet和TreeSet的区别
HashSet的底层是基于HashCode表进行存储的。
TreeSet的底层是基于平衡有序二叉树(又称红黑树)实现的。
1.6 HashMap和TreeMap的区别
HashMap,TreeMap的底层和Set接口中HashSet,TreeSet底层实现结构类似。Set中只能存放单个元素,Map中只能存储单对元素。
1.7 List,Set,Map的比较
List接口是有序的,存储的是单个元素,元素允许重复。
Set接口是无序的,存储的是单个元素,元素不允许重复。
Map接口是采用(key)键-(value)值进行存储,其中key不允许重复,value允许重复。
二,List接口及其常用实现类
List中的元素是有序的。实现List接口中的常用子类有:ArrayList,LinkedList,Stack,Vector
2.1 ArrayList类
由于数组是内存中一段连续的存储空间,因此可以非常方便地通过下标来访问和修改元素。如果在数组的开始和末尾增加或删除元素还比较容易,但是在数组中间增加或是删除某个元素,那么就需要移动其它的元素位置,若数组长度非常大,那么移动的元素就非常多,效率就比较低。
由于ArrayList的底层实现和数组类似,下面通过一个简单的Demo来看一看:
1 int []arr=new int[10]; 2 /* 3 * 赋值 4 */ 5 for(int i=0;i<arr.length;i++){ 6 arr[i]=i; 7 } 8 /* 9 * 打印 10 */ 11 System.out.print("原数组:"); 12 for(int i:arr){ 13 System.out.print(i+" ");// 0 1 2 3 4 5 6 7 8 9 14 } 15 System.out.println(); 16 /* 17 * 移除数组下表为6的元素 18 */ 19 int index=5; 20 for(int i=index;i<arr.length-1;i++){ 21 arr[i]=arr[i+1]; 22 } 23 /* 24 * 打印 25 */ 26 System.out.print("修改后:"); 27 for(int i:arr){ 28 System.out.print(i+" ");// 0 1 2 3 4 6 7 8 9 9 29 }
上面的代码移除了原数组下标为6的元素,并且移动了数组4次。
ArrayList的底层是采用动态数组实现的,访问和修改方便,增删不方便。
2.2 LinkedList类
附上一张图片来说明LinkedList和ArrayList的区别
LinkedList类的底层是采用动态链表实现的,增删方便,访问和修改不方便。
2.3 Stack类
该类的数据存储结构同栈类似,也是后进先出。
Stack类是采用动态数组的方式实现的,该类是一种具有后进先出特性的数据结构,简称LIFO(Last Input First Output)。
Stack类是Vector类的一个子类,它模拟了“栈”这种数据存储结构,Stack类是一个古老的类,也是线程安全、效率较低的一个类。不建议使用Stack类,如果需要“栈”这种结构可以考虑使用ArrayDeque代替。
2.4 Vector类
该类是采用动态数组的方式实现的,与ArrayList类相比,支持线程安全,效率比较低,Java官方推荐使用ArrayList。
到这里都知道Vector和ArrayList都是List的实现类,在上面关于ArrayList的介绍中,我们已经知道了ArrayList其实是基于动态数组结构的,其实Vector和ArrayList类似,也是基于动态数组。ArrayList和Vector对象是采用initialCapacity参数来设置数组的长度,当ArrayList对象和Vector对象添加的元素超过了数组的长度,initialCapacity会自动增加。如果在创建ArrayList和Vector对象的时候不指定initialCapacity的值,默认的长度是10。我们已经知道官方推荐使用ArrayList代替Vector,那么如何解决ArrayList不是线程安全的问题呢?其实JDK官方提供一个Collections的工具类,可以使用该类实现ArrayList的线程安全,比如: ArrayList arrayList= Collections.synchronizedList(new ArrayList(...));
2.5 其它
2.5.1 在List集合中存储自定义数据
在List集合中的数据是按照数组结构存储的,因此如果在List集合中存储自定义类数据的时候,不需要在自定义类中继承或是实现某些特殊的接口。
Student类:
1 public class Student { 2 3 private String name;//姓名 4 private int age;//年龄 5 6 public Student() { 7 super(); 8 } 9 10 public Student(String name, int age) { 11 super(); 12 setName(name); 13 setAge(age); 14 } 15 16 public String getName() { 17 return name; 18 } 19 20 public void setName(String name) { 21 this.name = name; 22 } 23 24 public int getAge() { 25 return age; 26 } 27 28 public void setAge(int age) { 29 this.age = age; 30 } 31 }