java集合之List接口及实现类
一、List子接口
-
有序、有下标、可重复(可用for循环进行遍历)
-
方法:
-
add(int index,Object o):在index位置插入对象o
-
addAll(int index,COllection c):将一个集合中的元素添加到此集合中的index位置
-
get(int index):返回集合中指定位置的元素
-
subList(int fromIndex,int toIndex):返回fromIndex和toIndex之间的集合元素
-
...
public class ListDemo { /** * List:有序、有下标、可重复 * @param args */ public static void main(String[] args) { List list=new ArrayList(); List list1=new ArrayList(); list1.add("苹果13promax"); list1.add("小米10"); //增加元素 list.add("苹果13promax"); list.add("小米10"); list.add(0,"红米K30S");//通过下标来插入 list.add(0,"红米K30"); list.add(0,"红米K40"); System.out.println(list.toString()); //删除元素 list.remove("小米10"); list.remove(1); System.out.println(list.toString()); //遍历 System.out.println("-----------------for------------------"); //1.for for (int i = 0; i < list.size(); i++) { System.out.println(list.get(i)); } System.out.println("-----------------foreach------------------"); //2.foreach for (Object o : list) { System.out.println(o); } System.out.println("-----------------iterator------------------"); //3.迭代器iterator Iterator iterator = list.iterator(); while(iterator.hasNext()){ System.out.println(iterator.next()); } System.out.println("-----------------ListIterator()------------------"); //4.迭代器ListIterator ListIterator listIterator = list.listIterator(); while (listIterator.hasNext()){ listIterator.next(); }//此时游标已经到了最后一个对象的后面,因此可用下面的方式输出 while (listIterator.hasPrevious()){ System.out.println(listIterator.previous()); } System.out.println("-----------------ListIterator(index)------------------"); ListIterator listIterator1 = list.listIterator(1);//创建一个从1索引位置开始的List迭代器 while (listIterator1.hasNext()){ System.out.println(listIterator1.next()); } //判断 System.out.println(list.contains("苹果13promax"));//true System.out.println(list.contains("苹果13promax "));//false System.out.println(list.isEmpty()); } } //下面是第二个程序示例 public class ListDemo02 { public static void main(String[] args) { List list=new ArrayList(); list.add(20);//此处有自动装箱操作 list.add(40); list.add(50); list.add(60); //list.remove("40");//无法删除 //list.remove((Object)20);//需要先状装箱才能进行删除 //list.remove((Integer)40); System.out.println(list); //subList方法:截取List(包含头,不包含尾) List list2 = list.subList(1, 4); System.out.println(list2);//[40, 50, 60] } }
-
-
list实现类
-
ArrayList:
- 数组结构实现,查询快、增删慢(增加和删除要改变元素顺序)
- JDK1.2版本,运行效率快、线程不安全
-
Vector(一般不用了):
- 数组结构实现,查询快、增删慢
- JDK1.0,运行效率慢、线程安全
-
LinkedList:
-
链表结构实现,查询慢,增删快
-
链表结构是通过一个个节点连接,首先有个头,头指向第二个节点,依次往下,因此在查询时,就比较慢,而删除的话只需要改变对下个结点的指向,因此比较快
-
-
二、ArrayList
import java.util.ArrayList;
import java.util.Iterator;
import java.util.ListIterator;
public class ArrayListDemo {
public static void main(String[] args) {
ArrayList arrayList=new ArrayList();
Student s1=new Student("韩邦胜",20);
Student s2=new Student("宋平",20);
Student s3=new Student("韩平",20);
//新增
arrayList.add(s1);
arrayList.add(s2);
arrayList.add(s3);
System.out.println(arrayList.size());
System.out.println(arrayList);
//删除
arrayList.remove(new Student("韩平",20));//要使用这种方式删除,需要重写Student的equals方法
System.out.println(arrayList.size());
System.out.println(arrayList);
//遍历
System.out.println("——————————迭代器——————————");
Iterator it = arrayList.iterator();
while(it.hasNext()){
System.out.println(it.next());
}
System.out.println("——————————列表迭代器——————————");
ListIterator lit = arrayList.listIterator();
while(lit.hasNext()){
System.out.println(lit.next());
}
System.out.println("——————————列表迭代器逆序——————————");
while(lit.hasPrevious()){
System.out.println(lit.previous());
}
//包含
System.out.println(arrayList.contains(new Student("宋平",20)));
System.out.println(arrayList.isEmpty());
//查找
System.out.println(arrayList.indexOf(new Student("宋平",20)));
}
}
//以下为Student类:
public class Student {
private String name;
private int age;
public Student(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
@Override
public boolean equals(Object o) {
//1判断是不是同一个对象
if (o==this){
return true;
}
//2判断是不是null
if (o==null){
return false;
}
//3判断是不是Student类型
if (o instanceof Student){
//4判断属性值是否相等
if (((Student) o).getName()==this.name&&((Student) o).getAge()==this.age){
return true;
}
}
//5否则返回false
return false;
}
}
-
ArrayList源码分析
-
DEFAULT_CAPACITY = 10 默认容量为10
-
size 数组大小
-
public ArrayList() {
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}//ArrayList的构造方法,默认将DEFAULTCAPACITY_EMPTY_ELEMENTDATA空数组赋值给当前数组
```java
public boolean add(E e) {
ensureCapacityInternal(size + 1); // Increments modCount!!,每次传过去的值为size+1
elementData[size++] = e;
return true;
}//add方法
private void ensureCapacityInternal(int minCapacity) {
ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));//比较elementData和minCapacity大小返回大的
}
private void ensureExplicitCapacity(int minCapacity) {
modCount++;
// overflow-conscious code
if (minCapacity - elementData.length > 0)
grow(minCapacity);
}
private static int calculateCapacity(Object[] elementData, int minCapacity) {
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
return Math.max(DEFAULT_CAPACITY, minCapacity);//将这个数于默认的容量10进行比较,返回大的
}
return minCapacity;
}
//扩容的核心代码
private void grow(int minCapacity) {
// overflow-conscious code
int oldCapacity = elementData.length;
int newCapacity = oldCapacity + (oldCapacity >> 1);//右移1位,相当于除以2
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity;
if (newCapacity - MAX_ARRAY_SIZE > 0)
newCapacity = hugeCapacity(minCapacity);
// minCapacity is usually close to size, so this is a win:
elementData = Arrays.copyOf(elementData, newCapacity);
}
- 结论:不调用add时ArrayList的容量为0,当调用add时,容量为10,当size为10时,ArrayList扩容,扩容大小为基础的1.5倍,即10*1.5=15,依次往下推。
三、Vector(用的不多)
import java.util.Enumeration;
import java.util.ListIterator;
import java.util.Vector;
public class VectorDemo {
/**
* 存储结构:数组 和ArrayList差不多,比ArrayList安全,但相对较慢
* @param args
*/
public static void main(String[] args) {
Vector vector=new Vector();
//1.添加
vector.add("小米");
vector.add("苹果");
vector.add("华为");
System.out.println(vector.size());
System.out.println(vector);
//2.删除
//vector.remove(0);
//vector.remove("苹果");
//vector.clear();
//System.out.println(vector);
//3.遍历
//ListIterator列表迭代器
ListIterator lit = vector.listIterator();
while(lit.hasNext()){
System.out.println(lit.next());
}
//枚举器
Enumeration enumeration = vector.elements();
while (enumeration.hasMoreElements()){
System.out.println(enumeration.nextElement());
}
//4.查找
System.out.println(vector.contains("苹果"));
System.out.println(vector.isEmpty());
//5.其他方法
System.out.println(vector.firstElement());
System.out.println(vector.lastElement());
System.out.println(vector.elementAt(0));//返回索引处的元素
}
}
四、LinkedList
import java.util.Iterator;
import java.util.LinkedList;
import java.util.ListIterator;
public class LinkedListDemo01 {
public static void main(String[] args) {
LinkedList linkedList=new LinkedList();
Student s1=new Student("韩邦胜",20);
Student s2=new Student("韩胜",21);
Student s3=new Student("韩邦",22);
//添加
linkedList.add(s1);
linkedList.add(s2);
linkedList.add(s3);
System.out.println(linkedList.size());
System.out.println(linkedList);
//删除
// linkedList.remove(0);
// linkedList.remove(new Student("韩邦",22));
// System.out.println(linkedList.size());
// System.out.println(linkedList);
//遍历
//1.for
System.out.println("---------for------------");
for (int i = 0; i < linkedList.size(); i++) {
System.out.println(linkedList.get(i));
}
//2.foreach
System.out.println("---------foreach------------");
for (Object obj:linkedList) {
System.out.println(obj);
}
//3.iterator
System.out.println("---------iterator------------");
Iterator it = linkedList.iterator();
while(it.hasNext()){
System.out.println(it.next());
}
//4.listiterator
System.out.println("---------listiterator------------");
ListIterator lit = linkedList.listIterator();
while(lit.hasNext()){
System.out.println(lit.next());
}
//判断
System.out.println(linkedList.contains(s1));
System.out.println(linkedList.isEmpty());
System.out.println(linkedList.indexOf(s1));
}
}
-
LinkedList源码分析
- size():大小
- first:头结点
- last:尾结点
- add()方法
public boolean add(E e) { linkLast(e); return true; }
- linkLast(e)
void linkLast(E e) { final Node<E> l = last; final Node<E> newNode = new Node<>(l, e, null); last = newNode; if (l == null) first = newNode; else l.next = newNode; size++; modCount++; }
- Node类
private static class Node<E> { E item; Node<E> next; Node<E> prev; Node(Node<E> prev, E element, Node<E> next) { this.item = element; this.next = next; this.prev = prev; } }
- 分析linkLast,当添加第一个元素时,last为空,所以l为空,newNode调用Node类的构造方法,前一个为空,后一个也为空,将newNode赋值给last,l==null,所以first也是newNode。size++。
- 第二次add元素,last已经不是null了,newNode的前面指向last,并将last重新赋值为新的newNode,并将l的下个节点指向这个newNode,size++。
- 双向链表结构
- 删除的话只需要查到后断开那个链,接到下一个结点就行,因此比较快。
五、ArrayList和LinkedList区别
- ArrayList开辟的空间是连续的
- LinkedList开辟的空间不用是连续的
本文来自博客园,作者:一只快乐的小67,转载请注明原文链接:https://www.cnblogs.com/sp520/p/15934862.html