集合
什么是集合?
数组就是集合,集合实际上就是一个容器,可以容纳其他类型的数据。集合是一个容器,是一个载体,可以一次容纳多个对象。实际开发中,Java连接数据库,数据库当中有10条记录,当把这10个数据查询出来,在java中会把这10条数据封装成10Java对象,然后将10个Java对象放到某一个对象当中,将集合传到前端,然后遍历集合,将一个数据一个数据展现出来。
比如 ,装10个苹果的购物袋,运输物资的飞机就是一个集合。
集合中不能直接存储基本数据类型,集合也不能直接存储Java对象,集合当中存储的都是Java对象的内存地址。
集合和数组的区别
集合的长度是可变的,数组的长度固定
集合中只能是引用的类型,数组中可以是基本数据类型,也可以是引用数据类型。
集合可以存储不同的类型,数组只能存储同一种数据。
java中集合的架构图
List集合
有序集合(也称为序列 )。 该界面的用户可以精确控制列表中每个元素的插入位置。 用户可以通过整数索引(列表中的位置)访问元素,并搜索列表中的元素。
Collection是接口,他的实现类有:ArrayList,LinkedList ,Vector
Collection下面的方法List肯定有的,因为是继承关系,所以在List中也可以使用。想要了解List的常用方法请查阅我的上期博客点击即可进入:Collection
List集合中独有的方法
List方法中添加元素的方法
返回值 | 方法名 | 作用 |
---|---|---|
void | add(int index, E element) | 将指定的元素插入此列表中的指定位置(可选操作)。 |
boolean | addAll(int index, Collection c) | 将指定集合中的所有元素插入到此列表中的指定位置(可选操作)。 |
案例:
public class Demo1 {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("张三");
list.add("李四");
list.add("王五");
list.add("张三");
//有序的 可重复的
System.out.println(list);//[张三, 李四, 王五, 张三]
list.add(2, "赵六");
System.out.println(list);//[张三,李四,赵六,王五,张三]
List<String> list1 = new ArrayList<>();
list1.add("刘星");
list1.add("夏雪");
list1.add("小雨");
list.addAll(1, list1);
System.out.println(list);//[张三,刘星,夏雪,小雨,李四,赵六,王五,张三]
}
}
List方法中删除元素的方法
返回值 | 方法名 | 作用 |
---|---|---|
E | remove(int index) | 删除该列表中指定位置的元素(可选操作)。 |
boolean | removeAll(Collection c) | 从此列表中删除包含在指定集合中的所有元素(可选操作)。 |
案例:
public class Demo2 {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("张三");
list.add("李四");
list.add("王五");
list.add("张三");
//有序的 可重复的
System.out.println(list);//[张三, 李四, 王五, 张三]
list.add(2, "赵六");
System.out.println(list);//[张三,李四,赵六,王五,张三]
List<String> list1 = new ArrayList<>();
list1.add("刘星");
list1.add("夏雪");
list1.add("小雨");
list.addAll(1, list1);
System.out.println(list);//[张三,刘星,夏雪,小雨,李四,赵六,王五,张三]
System.out.println(list.remove(0));//返回被删除的元素
System.out.println(list);//目的是删除以后的集合的数据展示一下
//[刘星,夏雪,小雨,李四,赵六,王五,张三]
}
}
List方法中修改元素的方法
返回值 | 方法名 | 作用 |
---|---|---|
E | set(int index, E element) | 用指定的元素(可选操作)替换此列表中指定位置的元素。 |
案例:
public class Demo3 {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("张三");
list.add("李四");
list.add("王五");
list.add("张三");
//有序的 可重复的
System.out.println(list);//[张三, 李四, 王五, 张三]
list.add(2, "赵六");
System.out.println(list);//[张三,李四,赵六,王五,张三]
List<String> list1 = new ArrayList<>();
list1.add("刘星");
list1.add("夏雪");
list1.add("小雨");
list.addAll(1, list1);
System.out.println(list);//[张三,刘星,夏雪,小雨,李四,赵六,王五,张三]
System.out.println(list.set(2, "彩云"));//返回被修改的元素
System.out.println(list);//修改之后的集合
//[张三,刘星,彩云,小雨,李四,赵六,王五,张三]
}
}
List方法中返回,通过下标去查找,截取元素的方法
返回值 | 方法名 | 作用 |
---|---|---|
E | get(int index) | 返回此列表中指定位置的元素。 |
int | indexOf(Object o) | 返回此列表中指定元素的第一次出现的索引,如果此列表不包含元素,则返回-1。 |
int | lastIndexOf(Object o) | 返回此列表中指定元素的最后一次出现的索引,如果此列表不包含元素,则返回-1。 |
List | subList(int fromIndex, int toIndex) | 返回此列表中指定的 fromIndex (含)和 toIndex 之间的视图。 |
案例:
public class Demo4 {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("张三");
list.add("李四");
list.add("王五");
list.add("张三");
//有序的 可重复的
System.out.println(list);//[张三, 李四, 王五, 张三]
list.add(2, "赵六");
System.out.println(list);//[张三,李四,赵六,王五,张三]
List<String> list1 = new ArrayList<>();
list1.add("刘星");
list1.add("夏雪");
list1.add("小雨");
list.addAll(1, list1);
System.out.println(list);//[张三,刘星,夏雪,小雨,李四,赵六,王五,张三]
System.out.println(list.get(0));//张三
System.out.println(list.get(1));//刘星
System.out.println(list.get(2));//夏雪
System.out.println(list.get(3));//小雨
System.out.println(list.indexOf("张三"));//0
System.out.println(list.lastIndexOf("张三"));//7
System.out.println(list);
List<String> strings = list.subList(3, 5);
System.out.println(strings);//[小雨,李四]
}
}
List遍利集合方法
for循环遍利集合
public class Demo2 {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("张三");
list.add("李四");
list.add("王五");
list.add("张三");
System.out.println(list);
for (int i = 0; i < list.size(); i++) {
//通过索引获取元素
System.out.println(list.get(i));
//张三
//李四
//王五
//张三
}
}
}
增强for循环遍利集合
语法格式:
for (集合中元素的数据类型 临时变量 : 集合或者数组){
System.out.println(临时变量);
}
public class Demo2 {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("张三");
list.add("李四");
list.add("王五");
list.add("张三");
System.out.println(list);
//增强for循环
for (String s : list) {
System.out.println(s);
//张三
//李四
//王五
//张三
}
}
}
迭代器遍利集合
语法格式:
ListIterator<T> listiterator = 集合的对象的引用.listIterator();
While (listiterator.hasNext()){
System.out.println(listiterator.next());
}
public class Demo3 {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("张三");
list.add("李四");
list.add("王五");
list.add("张三");
System.out.println(list);
ListIterator<String> sli = list.listIterator();
while (sli.hasNext()) {
System.out.println(sli.next());
}
//此时光标已经在最下面了
while (sli.hasPrevious()) { //List中独有的向上遍利迭代器
System.out.println(sli.previous());
}
}
}
public class Demo4 {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("张三");
list.add("李四");
list.add("王五");
list.add("张三");
System.out.println(list);
//可以将指针(光标)放到指定的额位置上,然后移动光标对数据进行遍历
ListIterator<String> sli = list.listIterator(4);
while (sli.hasPrevious()) {
System.out.println(sli.previous());
}
}
}
ArrayList实现类
ArrayList是List接口的实现类,在使用的时候通常使用多态的形式(父类的引用指向子类的对象)的形式使用,实现类重写了接口中的方法,所以这里就不多介绍了。
ArrayList的底层是数组,而且默认的容量为:10。当存入的数据长度超过容量时就会自动经进行扩容。扩容的倍数为1.5倍
ArrayList的特征:
查询快,插入与删除慢 (什么意思呢? 因为Array底层为数组,数组可以根据下标进行查询,一个下标对应一个数据,时间复杂度为 o(1),插入删除慢是因为可能出现需要进行扩容的情况)
LinkedList实现类
LinkedList是List接口的实现类,在使用的时候通常使用多态的形式(父类的引用指向子类的对象)的形式使用,实现类重写了接口中的方法,所以这里就不多介绍了,接着我们来聊一聊LinkedList的底层知识。
LinkedList的底层为双向链表
LinkedList的特征:
查询慢,插入和删除快(什么意思呢?因为Linked底层为双向链表,链表是根据二分法进行查找的,时间复杂度为log以2为底n的对数,而插入与删除快是因为链表的特点,链表有前置结点和后继结点,插入时,只需要匹配前置结点与后置结点即可,删除则直接将下一个元素的前置结点赋值给被删除元素前一个的元素的后继结点即可,时间复杂度为 o(1))。
面试题:ArrayList和LinkedList和Vector的区别
ArrayList和Vector 底层是数组,但是Vector是线程安全的,所以效率底,开发中不用Vector
接下来介绍ArrayList和linkedListu区别:
1.ArrayList底层是数组
LinkedList底层是双向链表
2.ArrayList 的特征:
查询快: 底层是索引,有序的通过内存有序地址,直接找到 时间复杂度 o(1)
增删慢: 增加数据和删除数据有可能扩容。每次扩1.5倍。扩容的话,浪费内存浪费时间o(n)
3.LinkedList的特征:
查询慢:底层是二分法查找的算法 时间复杂度是log以2为底 n的对数
增删快:直接找前置结点 Node prev,后继结点 Node next
。时间复杂度是 o(1)
所以开发时候的用ArrayList
后续还要学习ArrayList的源码