概述:
在之前的学习中我们一般存储多个类型相同的元素时,使用数组来存储。但在使用数组时,会有数组一旦定义,长度不能改变的缺点,当我们数组存储容量到达最大值时要进行扩容操作后才可继续存储数据。在实际开发中我们更多要是用动态增长的容器来保存我们的数据。我们需要保存的逻辑可能各种各样,于是就有了各种各样的数据结构的实现,这就是我们今天要学的集合。
集合框架由很多接口、抽象类、具体类组成。
-
Cpllection接口-定义了一组对象方法,其子接口Set和List分别定义了存储方式
-
Set中的数据对象没有顺序且不可重复
-
-
List中数据对象有顺序且可以重复
Collection接口-定义了存取一组对象的方法,其子接口Set和List分别定义了存储方式
Collection接口中定义集合中共有的方法
add();添加元素至集合末尾
boolean remove();删除指定元素
int size();返回集合中存储元素个数
boolean contains(Collection<?>,c);判断集合中是否包含指定元素
boolean retainAll() 求交集,集合数据发生变化返回true,不变返回false
public class Demo1 { public static void main(String[] args) { // 定义两个ArrayList对象,并存入数据 ArrayList<java.lang.String> c= new ArrayList<>(); // ①对象.add() 向集合中添加数据 c.add("a"); c.add("b"); c.add("c"); c.add("d"); ArrayList<java.lang.String> c1=new ArrayList<>(); c1.add("a"); c1.add("b"); c1.add("c"); c1.add("d"); // ②将一个集合添加到另一个集合中去 对象.addAll(); c.addAll(c1); System.out.println(c); // ③比较两个集合是否相等 对象.equals(); System.out.println(c.equals(c1)); // ④判断集合中元素是否为空 对象.clear; System.out.println(c.isEmpty()); // ⑤清除集合中所有元素 对象.clear(); // c1.clear(); // System.out.println(c1.isEmpty()); true // ⑥删除指定元素,成功后返回true没有则返回false // System.out.println(c.remove("a")); // System.out.println(c); // ⑦在c中保留c1中交集元素,发生变化返回true,无变化返回false System.out.println(c.retainAll(c1)); // ⑧数组长度length,字符串长度length(),集合长度size() System.out.println(c.size()); // ⑨将集合转换为指定类型 // Object[] obj=c.toArray(); // System.out.println(obj); // ⑨将集合转换为指定类型数组 // String[] s=c.toArray(new String[c.size()]); // System.out.println(s); } }
增强for循环
为什么需要增强for循环?
简化数组和集合遍历。
想要使用增强for循环必须要了解它的格式
for(数据类型 变量名 :数组或者集合对象){ //循环体,变量即元素 }
注意:
增强for的底层依赖的是迭代器。
也就是说增强for就是迭代器的简写形式。
public class Demo3 { public static void main(String[] args) { List<Integer> list=new ArrayList(); list.add(10); list.add(20); list.add(30); list.add(40); list.add(50); list.add(60); for (Object obj:list){ System.out.print(obj+" "); } } }
-
List继承了Collection接口,有三个实现类
-
ArrayList 数组列表,数据采用数组方式存储。
ArrayList实现了长度可变的数组,在内存中分配连续空间,遍历元素和访问随机元素效率比较高
ArrayList的常用方法
add(int index,E element);向指定索引处添加元素
get(int index); 获取index处的元素
indexOf(Object o);获得集合中指定元素第一次出现的索引,如集合中无此元素则返回-1
lastIndexOf(Object o);获得集合中指定元素最后一次出现的索引,如集合中无此元素则返回-1
remove();删除并返回指定位置元素
removeRange(int formIndex,int toIndex)删除指定区间的元素()
set(int index,E element);用指定元素替此列表中指定位置的元素
public class Demo2 { public static void main(String[] args) { ArrayList<String> ars=new ArrayList(); // 向指定索引处添加元素 ars.add("a"); ars.add(1,"b"); ars.add("c"); ars.add("a"); ars.add("d"); ars.add("e"); ars.add("g"); // 获取指定索引处的元素 System.out.println(ars.get(4)); // 获得指定元素第一次出现的索引 System.out.println(ars.indexOf("a")); // 获得指定元素最后一次出现的索引 System.out.println(ars.lastIndexOf("a")); // 删除并返回集合中对应位置的元素 System.out.println(ars.remove(0)); // 用指定元素替此类表中指定位置的元素 ars.set(0,"a"); System.out.println(ars); } }
-
LinkList 链表
LinkList采用链表存储方式。插入、删除元素时效率比较高
add(int index,Object element);向指定索引位置添加元素
addFist(Object element) 向链表头位置添加元素
addList(Object element) 向链表尾位置添加元素
get(int index);得到指定位置的元素
removeFirst(Object o);删除并返回第一个出现的元素
removeLast(Object o);删除并返回最后一个元素
remove(int index); 删除指定位置的元素
getFirst(); 返回此列表的第一个元素
getLast();返回此列表的最后一个元素
-
Vector 数组列表,添加同步锁,线程安全
-
-
Set接口继承了Collection接口
Set中存储的元素是不重复的,但是也是无序的,Set中的元素时没有索引的
遍历方式:
因为没有索引无法用for循环遍历
1.增强for循环
2.迭代器遍历
-
Set接口的两个实现类
-
HashSet
Hash中的元素不可重复,但彼此调用equals方法比较,都返回false
底层数据结构时哈希表+链表
哈希表依赖哈希值存储
哈希表依赖哈希值存储底层存储结构:有三种数据结构
1.数组2.链表3.红黑树
添加元素的过程:根据元素计算出一个哈希值(例:"a"--97),进行计算,计算出元素在数组中的位置,将元素封装到一个Node对象中,将对象存储到对应位置。
然后继续存储元素进来,如果hash值是同一位置,将新的元素存入之前元素的下一位,当链表到达一定的条件,会转化为红黑树。
哈希数组默认是16.
负载因子是0.75即当数据存储到数组长度的3/4时数组扩容
哈希数组如果扩容,每次扩容原来的2倍
当链表长度为8,且哈希数组长大于等于64时,链表转化为红黑树
-
TreeSet
可以给Set集合中的元素进行指定方式的排序。存储的对象必须Comparable接口
TreeSet底层数据结构是二叉树(红黑树是一种自平衡的二叉树)
-
Map接口
-
HashMap
HashSet不能存储重复数据
在add()底层,每添加一个元素,会判断集合中是否已经包含此元素。
在底层使用hashCode()和equals()方法来判断内容是否重复
hashCode()和equals()
在Object类中:public native int hashCode();
native修饰的方法称为本地方法,java中未实现,具体操作系统中的方法
其它类中重写hashCode()都不是对象地址,而是根据对象内容计算出来哈希值。
equals()在String类中重写的方法中,通过循环,在实际应用时效率较低。
除在Object类中equals()比较引用对象地址,其它类中均比较内容是否相等。
-
TreeMap
按自然顺序或自定义顺序遍历键(key)。 TreeMap根据key值排序,key值需要实现Comparable接口, 重写compareTo方法。TreeMap根据compareTo的逻辑,对 key进行排序。 键是红黑树结构,可以保证键的排序和唯一性。
-