集合是容器
数组作为容器有一些不方便之处,不利于我们对容器中的元素进行增删改
java给我们提供了里外一种容器–集合,能方便地操作容器中的元素
数组和集合的区别
数组长度固定,集合长度可变
数组之后同时存储同一种数据类型,集合可以存很多种
数组既能存基本数据类型,也能存引用数据类型,集合只能存引用数据类型
集合是一个集合框架,由很多种集合所构成
总体上分为单列集合和双列集合
一、集合框架 数据结构
数据结构:一种数据的存储方式
常见的数据结构有:栈 队列 数组 链表 树 哈希表
数据结构的特点
栈 : 先进后出 后进先出 (如枪的弹匣 一个出口,先进的在最下面)
队列: 先进先出 后进后出 (两个口 先从第一个口进的先从第二个口出)
数组:查询快(有索引) 增删慢(每次增删都需要重新排列元素索引,相当于把增删后的元素重新放到另一个数组中)
链表:查询慢(需要从第一个节点开始挨个查) 增删快 (如同锁链 互相环套 分为很多个节点 每个节点有自己的地址值,节点分为数值域和地址域,地址域中存放下一个节点的地址,如此相互嵌套)
二、单列集合Collection
Collection是单列集合的父类接口,我们需要学习其下的两个子接口list接口和set接口,
list接口下我们需要学习三个子实现类ArrayList,LinkedList,vector,
set接口下我们需要学习三个子实现类HashSet,LinkedHashSet,TreeSet
A、单列集合Collection通用方法
Collection c = new ArraryList();//多态
//add 往集合中添加元素
c.add();//有一个布尔类型的返回值,可以查看是否添加成功
//addAll 将两个集合中元素添加到一个集合中
Collection c = new ArraryList();
c.add("1");
c.add("2");
c.add("3");
Collection d = new ArraryList();
d.add("1");
d.add("a");
d.add("b");
c.addAll(d);//将d中元素全部加到c中,d不会少元素,c与d中重复元素也在
//删除数据
//1.remove
c.remove();//删除集合中指定元素,返回布尔类型,代表删除是否成功
//2.clear 清空集合中所有元素
c.clear();
//3.boolean removeAll(); 移除一个集合的元素(移除一个以上就是true),删除的是两个集合的交际元素,如果没有交际元素则返回false
c.removeAll(d); //返回布尔
System.out.println(c);//将c中与d的交集元素删除
System.out.println(d);//d集合不变
//判断功能
//1.contains
c.contains("1");//判断集合中有没有指定元素
//2.boolean containsAll(); 判断一个集合中是否包含另一个集合中的所有元素
//3.判断是否为空 isEmpty();
c.clear();
c.isEmpty();//true
//获取集合的长度
c.size();//获取集合的长度
//获取迭代器(遍历器)
迭代器是ArraryList的一个内部类,能直接访问外部类ArraryList的信息,所以能直接遍历
Iterator i = c.iterator();
Iterator对Collection进行迭代(遍历)的迭代器
boolean hasNext(); 如果仍有元素可以迭代,返回true
E next(); 返回迭代的下一个元素
void remove(); 从迭代器中指定的Collection中移除迭代器返回的最后一个元素(可选操作)
Iterator i = c.iterator();
while(i.hasNext){
Object o = i.next();
System.out.println(o);
}
//retainsAll()
c.retainAll(d); 获取两个集合的交际元素,失败两个集合无变化,成功则只留交际元素放到c集合中,c中原有的非交集元素就被删除 返回布尔类型 代表c中有没有发生变化
System.out.println(c);
System.out.println(d);
//将集合中的元素转到数组中
Object[] o = c.toArray();
System.out.println(Arrays.toString(o));
//将数组转到集合中
Arrays.asList();
Integer[] arr = {132,465,132,42};
Integer[] arr1 = {132,465,132,42,312};
Integer[] arr2 = {132,465,132,42,49};
List<Integer> in = Arrays.asList(arr);//单个数组元素为引用类型的数组 将数组元素添到新集合中
List<Integer> in = Arrays.asList(arr,arr1,arr2);//单个基本类型数组或多个引用类型数组 将数组作为集合的元素
使用该方法转过来的集合 集合元素不能增删改
B、List
元素有序(存取元素的顺序一致),且允许重复元素
List l = new ArraryList();
l.add("asdf");
//List 中特有的添加方法 可以指定索引
l.add(0,"132");//在开头添加
l.add(1,"456");
l.remove(0,"12");//根据索引移除元素
当List集合中添加的是Integer类型数据时,我们根据元素移除时无法区分元素和索引,需要将元素包装下才行
//List根据索引获取元素 注意索引越界
Object o = l.get(0);
//List 根据索引替换元素
Object o = l.set(2,"qwe"); //返回被替换的旧元素
//遍历List集合的方式
1.Itrator迭代器
2.for循环 get方法 遍历
3.List集合中特有的迭代器 ListIterator Iterator的子接口
ListIterator L = l.listIterator();
ListIterator两个特有的方法 反向迭代 Previous 和 hasPrevious
必须正向迭代之后才能反向迭代,迭代器指针默认在开头,没有上一个元素
一个迭代器一个指针,必须同一个迭代器正向迭代之后才能反向迭代
使用next方法移动指针后 再迭代指针从被移动后的位置开始
boolean b = L.hasPrevious();判断有没有上一个元素
Object o = L.Previous(); 返回上一个元素
当我们在使用迭代器时,迭代器事先已经知道集合中元素的个数,在迭代过程中增加或删除集合中的元素会有 并发修改异常 ConcurrentModificationException
迭代过程中如果要添加或删除元素,可以使用迭代器的添加或删除元素的方法
List l = new ArraryList();
ListIterator L = l.listIterator();
L.add();
L.remove
1. ArrayList
底层数据结构是数组 查询快 增删慢 线程不安全 效率高
两个父接口 Collection List
ArrayList a = new ArrayList();//初始容量为10 超过自动扩充 参数可指定容量
a.add(100);
a.add(200);
a.add(300);
a.add(400);
a.add(30);
int i = a.indexOf(300);//2
int i = a.lastIndexOf(300);//2
a.sort(new );//排序 需要一个比较器Comparatar
a.subList(0,2);//根据起始索引与终止索引截取元素到新集合中
Object o = a.clone();//克隆一个集合
遍历ArrayList
1.Iterator l = a.iterator();
2.ListIterator l = a.listIterator();
3.for循环
4.a.forEach(new Consumer) 创建Consumer接口
2 .Vector
底层数据结构是数组 查询快 增删慢 线程安全 效率低
Vector v = new Vector();
v.add();
v.addElement();
Object o = v.get(0);
Object o = v.elementAt(0);
Object o = v.firstElement(0);
Object o = v.lastElement(0);
Object o = v.get(v.size-1);
v.removeAllElements();
v.clear();
Enumeration e = v.elements();
e.hasMoreElements();
e.nextElement();
3. LinkedList
底层数据结构是链表,查询慢增删快 线程不安全 效率高
根据需求选择集合容器
LinkedList l = new LinkedList();
l.add();
l.addFirst();
l.addLast();
l.peek(); //获取但不移除此列表中的第一个元素
l.pop(); //从此列表所处的堆栈处弹出一个元素(获取并去除此列表中的第一个元素)
l.poll(); //获取并去除此列表中的第一个元素
l.push(); //将元素推入此列表所表示的堆栈(在列表最开头加入指定元素)
B. Set
Set集合特点:元素唯一
1.HashSet
底层数据结构是哈希表(JDK1.8后数组+链表+二叉树/红黑树 当同一个桶中元素超过8时(查询慢),就会将链表转为红黑树)就像新华字典
HashSet底层用HashMap集合来存的
特点:元素无序(存取顺序不一致/取元素顺序和存元素顺序没有关系)且唯一(元素不能重复)
HashSet<String> h = new HashSet();
h.add("1");
h.add("1");
h.add("3");
h.add("2");
for(String s: h){
System.out.println(h);//1 2 3
}
HashSet之所以能保证元素的唯一性 是靠元素重写equals()方法 如果元素不重写,则不能保证元素唯一性
合理地重写hashCode方法,可以减少调用equals()方法的次数(减少碰撞)
2.LinkedHashSet
元素有序(存取顺序一致)且唯一
底层数据结构是链表和哈希表 链表保证有序 哈希表保证唯一
线程不安全效率高
3.TreeSet
元素唯一且可以对元素进行排序
排序分两种方式:自然排序,比较器排序
底层数据结构是二叉树 元素获取规则:左 中 右
TreeSet<Integer> ts = new TreeSet<>();
TreeSet.add(20);
TreeSet.add(18);
TreeSet.add(23);
TreeSet.add(22);
TreeSet.add(17);
TreeSet.add(24);
TreeSet.add(19);
TreeSet.add(18);
TreeSet.add(24);
System.out.println(ts);//已从小到大排好序且重复元素已去除
TreeSet<Student> ts = new TreeSet<>();//自然排序 如果采用的是空参构造,采用的就是自然排序 自然排序对元素的要求:元素必须实现Comparable接口,并重写Comparable接口的的compareTo比较方法,根据此方法返回值的正负0决定元素排列位置
TreeSet.add(new Student("张三",20));
TreeSet.add(new Student("李四",23));
TreeSet.add(new Student("王五",30));
TreeSet.add(new Student("周六",33));//报错 空参构造 Studenta还没有重写compareTo比较方法
//比较器排序
采用有参构造,创建TreeSet对象时,需要传入Comparator接口(比较器) /* 自建Comparator接口子实现类MyComparator或者匿名内部类*/ 重写campare方法 根据返回值正负零进行排序
TreeSet<Student> ts = new TreeSet<>(Comparator接口子实现类);
Collections 工具类,针对的是Collection集合,提供了一些方法
Collections.shuffle(new ArrayList()); //随机打乱集合中的元素
Collections.sort(list);//排序 也可以再传入一个比较器根据比较器排序
Collections.reverse();//反转集合汇总的元素
Collections.binarysearch(list,10);//二分查找
Collections.max(list);
Collections.min(list)