本文已参与[新人创作礼]活动,一起开启掘金创作之路。
哈喽,大家好!我是Why,一名在读学生,目前刚刚开始进入自己的编程学习生涯。虽然学习起步较晚,但我坚信做了才有0或1的可能。学了一段时间以后也是选择在掘金上分享自己的日常笔记,也希望能够在众多道友的大家庭中打成一片。 本文主要讲解Java集合之——List,如果大家读后觉得有用的话,还请大家多多支持博主:欢迎 ❤️点赞👍、收藏⭐、留言💬 ✨✨✨个人主页:JinHuan List接口作为Collection的三大子类型接口之一,自然拥有Collection接口中的所有方法。且List作为列表类型父接口,也具有着自己独特的方法。
此接口其定义为:
public interface List<E> extends Collection<E>
老样子,先看继承树,再讲解常用方法,如下所示:
不难看出,List下最常用的列表子类有 ArrayLIst,Vector 以及LinkedList,前两个最为常用,使用场景几乎占到99%,本文也将对ArrayLIst,Vector进行进一步的讲解,有关Collection接口以及java中的的叙述,可以参考我的这篇文章:
常用方法
| 方法 | 描述 |
|---|---|
| public boolean add(E e) | 向集合中插入一个元素 |
| public boolean addAll(Collection<? extends E> c) | 向集合中插入一组元素 |
| public void clear() | 清空集合中的元素 |
| public boolean contains(Object o) | 查找一个元素是否存在 |
| public boolean containsAll(Collection<?> c) | 查找一组元素是否存在 |
| public boolean isEmpty() | 判断集合是否为空 |
| public Iterator iterator() | 为 Iterator 接口实例化 |
| public boolean remove(Object o) | 从集合中删除一个对象 |
| boolean removeAll(Collection<?> c) | 从集合中删除一组对象 |
| boolean retainAll(Collection<?> c) | 判断是否没有指定的集合 |
| public int size() | 求出集合中元素的个数 |
| public Object[] toArray() | 以对象数组的形式返回集合中的全部内容 |
| T[] toArray(T[] a) | 指定操作的泛型类型,并把内容返回 |
| public boolean equals(Object o) | 从 Object 类中覆写而来 |
| public int hashCode() | 从 Object 类中覆写而来 |
可以看出List接口独有的方法均与索引(index)有关,这是因为List接口代表的是列表类型,以线性方式存储对象,故List对象可以根据元素位置使用索引值直接操作数据。
实例
package com.blog.list;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
/**
* @Author jinhuan
* @Date 2022/4/13 8:56
* Description:
*/
public class Test01 {
public static void main(String[] args) {
//以ArrayList为例子
//注意面向接口编程思想
List list01 = new ArrayList();
//public boolean add(E e)
list01.add("123");
System.out.println("List01-->"+list01);
//public boolean addAll(Collection<? extends E> c)
List list02 = new ArrayList();
list02.addAll(list01);
System.out.println("List02-->"+list02);
//public void clear()
list02.clear();
System.out.println("List02使用clear之后-->"+list02);
//public boolean contains(Object o)
System.out.println(list01.contains("123") ? "包含123" : "不包含123");
System.out.println(list01.contains("456") ? "包含456" : "不包含456");
//public boolean containsAll(Collection<?> c)
List list03 = new ArrayList();
//先把list01里面的元素全部添加进list03
list03.addAll(list01);
list03.add("21323");
list03.add("234");
list03.add("2345");
System.out.println(list03.containsAll(list01) ? "list03包含list01" : "list03不包含list01");
//public boolean isEmpty()
System.out.println(list01.isEmpty() ? "List01为空" : "List01不为空");
System.out.println(list02.isEmpty() ? "List02为空" : "List02不为空");
System.out.println(list03.isEmpty() ? "List03为空" : "List03不为空");
//public Iterator<E> iterator()
Iterator iterator = list03.iterator();
System.out.println("对list03进行迭代:");
while(iterator.hasNext()){
System.out.print(iterator.next()+" ");
}
System.out.println();
System.out.println("迭代完毕");
//boolean retainAll(Collection<?> c)
System.out.println(list03.retainAll(list01) ? "包含" : "不包含");
//public boolean remove(Object o)
list03.remove("234");
list03.removeAll(list01);
//public int size()
System.out.println(list01.size());
//public Object[] toArray()
List<Integer> list04 = new ArrayList<>();
list04.add(1);
list04.add(2);
list04.add(3);
Object[] objects = list04.toArray();
//<T> T[] toArray(T[] a)
List<Integer> list05 = new ArrayList<>();
list05.add(1);
list05.add(2);
list05.add(3);
Integer[] integers = new Integer[]{};
list05.toArray(integers);
//注意,也可以直接使用数组接收
Integer[] integerss = list05.toArray(new Integer[]{});
//public boolean equals(Object o)
System.out.println("list05的ToString方法(调用方法):"+list05.toString());
//因为List已经重写了Tostring方法,所以直接输出就可以
System.out.println("list05的ToString方法(直接输出):"+list05);
//public int hashCode()
System.out.println("list05的hashCode方法(哈希值):"+list05.hashCode());
}
}
运行截屏
ArrayList
import java.util.ArrayList;
import java.util.List;
/*
ArrayList集合:
1、默认初始化容量10(底层先创建了一个长度为0的数组,当添加第一个元素的时候,初始化容量10。)
2、集合底层是一个Object[]数组。
3、构造方法:
new ArrayList();
new ArrayList(20);
4、ArrayList集合的扩容:
增长到原容量的1.5倍。
ArrayList集合底层是数组,怎么优化?
尽可能少的扩容。因为数组扩容效率比较低,建议在使用ArrayList集合
的时候预估计元素的个数,给定一个初始化容量。
5、数组优点:
检索效率比较高。(每个元素占用空间大小相同,内存地址是连续的,知道首元素内存地址,
然后知道下标,通过数学表达式计算出元素的内存地址,所以检索效率最高。)
6、数组缺点:
随机增删元素效率比较低。
另外数组无法存储大数据量。(很难找到一块非常巨大的连续的内存空间。)
7、向数组末尾添加元素,效率很高,不受影响。
8、面试官经常问的一个问题?
这么多的集合中,你用哪个集合最多?
答:ArrayList集合。
因为往数组末尾添加元素,效率不受影响。
另外,我们检索/查找某个元素的操作比较多。
7、ArrayList集合是非线程安全的。(不是线程安全的集合。)
*/
public class ArrayListTest01 {
public static void main(String[] args) {
// 默认初始化容量是10
// 数组的长度是10
List list1 = new ArrayList();
// 集合的size()方法是获取当前集合中元素的个数。不是获取集合的容量。
System.out.println(list1.size()); // 0
// 指定初始化容量
// 数组的长度是20
List list2 = new ArrayList(20);
// 集合的size()方法是获取当前集合中元素的个数。不是获取集合的容量。
System.out.println(list2.size()); // 0
list1.add(1);
list1.add(2);
list1.add(3);
list1.add(4);
list1.add(5);
list1.add(6);
list1.add(7);
list1.add(8);
list1.add(9);
list1.add(10);
System.out.println(list1.size());
// 再加一个元素
list1.add(11);
System.out.println(list1.size()); // 11个元素。
/*
源码:
int newCapacity = ArraysSupport.newLength(oldCapacity,minCapacity - oldCapacity,oldCapacity >> 1);
*/
// 100 二进制转换成10进制: 00000100右移一位 00000010 (2) 【4 / 2】
// 原先是4、现在增长:2,增长之后是6,增长之后的容量是之前容量的:1.5倍。
// 6是4的1.5倍
}
}
Vector
import java.util.*;
/*
Vector:
1、底层也是一个数组。
2、初始化容量:10
3、怎么扩容的?
扩容之后是原容量的2倍。
10--> 20 --> 40 --> 80
4、ArrayList集合扩容特点:
ArrayList集合扩容是原容量1.5倍。
5、Vector中所有的方法都是线程同步的,都带有synchronized关键字,
是线程安全的。效率比较低,使用较少了。
6、怎么将一个线程不安全的ArrayList集合转换成线程安全的呢?
使用集合工具类:
java.util.Collections;
java.util.Collection 是集合接口。
java.util.Collections 是集合工具类。
*/
public class VectorTest {
public static void main(String[] args) {
// 创建一个Vector集合
List vector = new Vector();
//Vector vector = new Vector();
// 添加元素
// 默认容量10个。
vector.add(1);
vector.add(2);
vector.add(3);
vector.add(4);
vector.add(5);
vector.add(6);
vector.add(7);
vector.add(8);
vector.add(9);
vector.add(10);
// 满了之后扩容(扩容之后的容量是20.)
vector.add(11);
Iterator it = vector.iterator();
while(it.hasNext()){
Object obj = it.next();
System.out.println(obj);
}
// 这个可能以后要使用!!!!
List myList = new ArrayList(); // 非线程安全的。
// 变成线程安全的
Collections.synchronizedList(myList); // 这里没有办法看效果,因为多线程没学,你记住先!
// myList集合就是线程安全的了。
myList.add("111");
myList.add("222");
myList.add("333");
}
}
区别
| 区别点 | ArrayList | Vector |
|---|---|---|
| 时间 | 新的类,在jdk1.2之后推出 | 元老类,在jdk1.0就已经存在 |
| 性能 | 性能较高,因为采用了异步处理 | 性能较低,采用了同步处理(线程安全) |
| 输出 | 支持Iteractor,ListIteractor | 除了支持Iteractor,ListIteractor,还额外支持Enumeration输出 |
好啦,这就是关于List接口中最常用方法的简单描述以及list的最常用子类ArrayLIst以及Vector的介绍了,希望能够帮助到大家,另外,我自己整理了一些自资源(笔记、书籍、软件等)分享在我的公众号上,非常欢迎大家来访白嫖和博主做朋友,一起学习进步!最后别忘啦支持一下博主哦,求三连!❤️❤️❤️