一、为什么需要集合
如果要将100个学生成绩存放到程序中,怎么做?
首先想到是数组
int[] scores=new int[100];
然而,长度是固定的,比如是101个学生成绩,这个数组就不能用了,越界。
另外如果只使用了10个,则另外90个都被浪费了。
总之:集合是数组的升级,长度是动态的,无需预定义
使用Array(数组)存储对象方面具有一些弊端,需要提前对数组进行容量大小的设定,而Java 集合就像一种容器,可以动态地把多个对象的引用放入容器中,不要提前设置容量大小,存多少个就是多少个,无需提前定义。
数组是很常用的一种的数据结构,我们用它可以满足很多的功能,但是,有时我们会遇到如下这样的问题:
1、我们需要该容器的长度是不确定的。
2、我们需要它能自动排序。
3、我们需要存储以键值对方式存在的数据。
Java是一种面向对象语言,如果我们要针对多个对象进行操作,就必须对多个对象进行存储。而数组长度固定,不能满足变化的要求。所以,java提供了集合。
特点
1. 长度可以发生改变
2. 只能存储对象
3. 可以存储多种类型对象
二、Java常用集合类型
Collection 接口存储一组不唯一,无序的对象
List 接口存储一组不唯一,有序(插入顺序)的对象,类似数组
Set 接口存储一组唯一,无序的对象
Map接口存储一组键值对象,提供key到value的映射,Key不允许重复
List 允许重复,有序
set 不允许重复,无序
map value可重复,key不可重复,无序
二、List与ArrayList
1、Collection常用方法
1.1、添加功能
boolean add(Object obj):向集合中添加一个元素
boolean addAll(Collection c):向集合中添加一个集合的元素
1.2、删除功能
void clear():删除集合中的所有元素
boolean remove(Object obj):从集合中删除指定的元素
boolean removeAll(Collection c):从集合中删除一个指定的集合元素
1.3、判断功能
boolean isEmpty():判断集合是否为空。
boolean contains(Object obj):判断集合中是否存在指定的元素。
boolean containsAll(Collection c):判断集合中是否存在指定的一个集合中的元素。
1.4、遍历功能
Iterator iterator():就是用来获取集合中每一个元素。
1.5、长度功能
int size():获取集合中的元素个数
1.6、交集功能
boolean retainAll(Collection c):判断两个集合中是否有相同的元素
1.7、把集合转换成数组
Object[] toArray():把集合变成数组。
2、List接口
List接口为Collection直接接口。List所代表的是有序的Collection,即它用某种特定的插入顺序来维护元素顺序。用户可以对列表中每个元素的插入位置进行精确地控制,同时可以根据元素的整数索引(在列表中的位置)访问元素,并搜索列表中的元素。实现List接口的集合主要有:ArrayList、LinkedList、Vector、Stack。
add方法用于添加一个元素到当前列表的末尾,也可以通过其重载形式指定添加的位置;
addAll方法用于添加一个集合到当前列表的末尾,主要用于批量添加;
remove方法用于删除列表中的一个元素,可以将需要删除的元素作为参数进行指定,也可以指定需要删除元素的下标;
removeAll方法用于一次删除多个元素,参数为集合,集合中包含需要删除的元素;
get 方法用于通过下标获取对应下标的元素;
set 方法用于修改对应下标的元素;
size 方法用于获得集合的长度;
另外,还有几个类似的方法:
clear 方法用于清除现有所有的元素;
contains 方法用来查找某个对象在不在列表之中;
3、ArrayList
ArrayList是一个动态数组,也是我们最常用的集合。它允许任何符合规则的元素插入甚至包括null。每一个ArrayList都有一个初始容量(10),该容量代表了数组的大小。随着容器中的元素不断增加,容器的大小也会随着增加。在每次向容器中增加元素的同时都会进行容量检查,当快溢出时,就会进行扩容操作。所以如果我们明确所插入元素的多少,最好指定一个初始容量值,避免过多的进行扩容操作而浪费时间、效率。
size、isEmpty、get、set、iterator 和 listIterator 操作都以固定时间运行。add 操作以分摊的固定时间运行,也就是说,添加 n 个元素需要 O(n) 时间(由于要考虑到扩容,所以这不只是添加元素会带来分摊固定时间开销那样简单)。
ArrayList擅长于随机访问,ArrayList是非同步的。public static void main(String[] args) {
//定义list集合,指定存放的数据类型,只能是引用类型 List<Integer> list = new ArrayList<Integer>(); //添加单个元素 Integer n = 88; list.add(98); list.add(78); list.add(68); list.add(58); list.add(n); //获得单个元素 int e1 = list.get(0);//获取list第一个元素98 System.out.println(e1); //获得集合长度 System.out.println("长度为:"+list.size()); //遍历集合方式1 for (Integer l : list) { System.out.println("遍历:"+l); } //遍历集合方式2 for(int i=0;i<list.size();i++) { System.out.println("遍历:"+list.get(i)); } //移除 //将下标为0的元素98移除 list.remove(0); //移除所有 list.clear(); //获得集合长度 System.out.println("长度为:"+list.size()); }
打印输出:
98
长度为:5
遍历:98
遍历:78
遍历:68
遍历:58
遍历:88
遍历:98
遍历:78
遍历:68
遍历:58
遍历:88
长度为:0
ArrayList操作
public static void main(String[] args) { ArrayList<String> l = new ArrayList<String>(); l.add("Tom"); l.add("Jerry"); l.add("Micky"); //使用iterator遍历元素 Iterator<String> it = l.iterator(); while(it.hasNext()) { String str = it.next(); System.out.println(str); } //在指定位置插入元素 l.add(2, "kate"); System.out.println(); //通过索引直接访问元素 for(int i =0;i<l.size();i++) { System.out.println(l.get(i)); } ArrayList<String> subList = new ArrayList<String>(); subList.add("Mike"); subList.add("Jack"); // addAll(Collection<? extends String> c)添加所给集合中的所有元素 l.addAll(subList); System.out.println("-------------------------------------"); //遍历元素 for(int i =0;i<l.size();i++) { System.out.println(l.get(i)); } // 判断是否包含某个元素 if(l.contains("Mike")) { System.out.println("Mike is include in the list"); } } 打印输出: Tom Jerry Micky Tom Jerry kate Micky ------------------------------------- Tom Jerry kate Micky Mike Jack Mike is include in the list
LinkedList操作
public static void main(String[] args) { LinkedList<String> linkedList = new LinkedList<String>(); linkedList.add("Tom"); linkedList.add("Jack"); linkedList.add("Rose"); linkedList.add("Katy"); linkedList.remove("Tom"); Iterator<String> iterator = linkedList.iterator(); while(iterator.hasNext()) { System.out.println(iterator.next()); } } 打印输出: Jack Rose Katy
三、Set与HashSet
Set是一种不包括重复元素的Collection。它维持它自己的内部排序,所以随机访问没有任何意义。与List一样,它同样运行null的存在但是仅有一个。由于Set接口的特殊性,所有传入Set集合中的元素都必须不同,同时要注意任何可变对象,如果在对集合中元素进行操作时,导致e1.equals(e2)==true,则必定会产生某些问题。实现了Set接口的集合有:EnumSet、HashSet、TreeSet。
EnumSet
是枚举的专用Set。所有的元素都是枚举类型。
HashSet
HashSet堪称查询速度最快的集合,因为其内部是以HashCode来实现的。它内部元素的顺序是由哈希码来决定的,所以它不保证set 的迭代顺序;特别是它不保证该顺序恒久不变。
HashSet基础操作
ArrayList<Integer> list = new ArrayList<Integer>(); list.add(3); list.add(4); HashSet<Integer> set = new HashSet<Integer>(); set.add(1); set.add(3); set.add(2); set.add(6); //set重复的元素将不能被添加 set.add(1); //只要有元素被添加就返回true if(set.addAll(list)) { System.out.println("Add success"); } //判断是否存在某个集合 if(set.containsAll(list)) { System.out.println("The set is contain 3 and 4"); } Iterator<Integer> it = set.iterator(); while(it.hasNext()) { System.out.print(it.next()+" "); } //转换成数组 Object[] array = set.toArray(); for(int i=0;i<array.length;i++) { System.out.print(array[i]); } set.remove(3); }
打印输出:
Add success
The set is contain 3 and 4
1 2 3 4 6 12346
TreeSet
基于TreeMap,生成一个总是处于排序状态的set,内部以TreeMap来实现。它是使用元素的自然顺序对元素进行排序,或者根据创建Set 时提供的 Comparator 进行排序,具体取决于使用的构造方法。
public static void main(String[] args) { TreeSet<String> treeSet = new TreeSet<String>(); treeSet.add("C"); treeSet.add("A"); treeSet.add("D"); treeSet.add("B"); Iterator<String> it = treeSet.iterator(); while(it.hasNext()) { System.out.println(it.next()); } }
四、总结