首页 > 其他分享 >List集合

List集合

时间:2023-02-13 15:37:19浏览次数:53  
标签:List ArrayList 元素 list add 集合 new


List集合

  • ​​1、List集合​​
  • ​​1.1 List接口的方法​​
  • ​​1.2 案例:元素的增删改查​​
  • ​​1.3 List接口的实现类​​
  • ​​1.3.1 ArrayList类​​
  • ​​1.3.2 LinkedList类​​
  • ​​1.3.3 Vector类​​
  • ​​1.3.4 Stack类​​
  • ​​1.4 List集合的遍历​​
  • ​​1.4.1 普通for遍历循环遍历(效率不高)​​
  • ​​1.4.2 ListIterator迭代器​​
  • ​​1.4.3 foreach循环遍历​​
  • ​​1.4.4 Iterator迭代器遍历​​

1、List集合

  Collection接口没有提供直接的实现类,而是提供了更加具体的子接口的实现类,其中一个最常用的子接口就是List接口。List集合中的元素是有序、可重复的

   List集合关心集合是否有序,而不关心元素是否重复。

1.1 List接口的方法

  List除可以从Collection集合继承的方法,List集合中还添加了一些根据索引来操作集合的方法。之前我们说Collection接口中没有提供修改元素的方法,而List接口中提供了根据元素的下标索引位置来修改元素的方法set,下面列出了List接口新增的方法。

(1)添加元素

  • ​void add(int index,Object element)​​:在[index]位置添加一个元素。
  • ​boolean addAll(int index,Collection eles)​​:在[index]位置添加多个元素。

(2)获取元素

  • ​Object get(int index)​​:获取[index]位置的元素。
  • ​List subList(int fromIndex,int toIndex)​​:获取[fromIndex,toIndex)范围的元素。

(3)获取元素索引

  • ​int indexOf(Object obj)​​:获取obj在List集合中首次出现的索引位置,如果不存在则返回-1.
  • ​int lastIndexOf(Object obj)​​:获取obj在List集合中最后出现的索引位置,如果不存在则返回-1.

(4)删除和替换元素

  • ​Object remove(int index)​​:删除[index]位置的元素。
  • ​Object set(int index,Object element)​​:替换[index]位置的元素为element。

  因为List接口是Collection接口的子接口,因此之前Collection接口的方法,List接口也同样适用,Collection集合的遍历方式也同样适用于List接口的集合。

1.2 案例:元素的增删改查

  案例1:添加元素:

public class ListAddTest {
public static void main(String[] args) {
ArrayList<Object> list = new ArrayList<>();
list.add("张三");
list.add(0,"李四");//把“李四”添加到索引[0]位置
list.add(1,"王五");
for (Object o : list) {
System.out.println(o);
}
}
}

List集合_集合

  案例2:获取指定位置元素

public class ListGetTest {
public static void main(String[] args) {
ArrayList list = new ArrayList<>();
list.add("张三");
list.add("李四");
list.add("王五");

Object o = list.get(1);
System.out.println(o);
}
}

List集合_System_02

  案例3:获取指定位置元素索引位置

public class ListGetTest {
public static void main(String[] args) {
listIndexOfTest();
}
public static void listIndexOfTest(){
ArrayList<Object> list = new ArrayList<>();
list.add("张三");
list.add("李四");
list.add("王五");
list.add("李四");

//从[0]开始查找,返回第一次出现的"李四“的索引
int index = list.indexOf("李四");
System.out.println("index="+index);
}
}

List集合_数据结构_03

  案例4:删除指定[0]位置的元素“张三”

import java.util.ArrayList;

public class ListRemoveTest {
public static void main(String[] args) {
ArrayList<Object> list = new ArrayList<>();
list.add("张三");
list.add("李四");
list.add("王五");

list.remove(0);//删除索引为[0]的元素。
list.forEach(System.out::println);
}
}

List集合_数据结构_04

  案例5:删除指定元素“2”

public class ListRemoveTest2 {
public static void main(String[] args) {
ArrayList<Object> list = new ArrayList<>();
list.add(1);
list.add(2);
list.add(3);
list.add(4);

list.remove(2);
list.forEach(System.out::println);
}
}

List集合_System_05

  上面运行结果是1,2,4,而不是1,3,4,这是因为现在List接口中有两个remove方法,一个是​​remove(Object obj)​​​,另一个是​​remove(int index)​​​,而上面代码中​​list.remove(2)​​​匹配的是​​remove(int index)​​,删除的是[2]位置的元素3.

  因为添加到集合中的1,2,3,4已经自动装箱为​​Integer​​​的对象了,所以如果要删除元素2,那么可以通过​​list.remove(Integer.valueOf(2))​​​的方法实现或使用迭代器配合​​equals​​判断是否是2再删除。

1.3 List接口的实现类

  List接口的实现类都具备List接口有序且可以重复的特点,使用方式完全一样,仅仅是底层存储结构不同。这里列举了List接口中比较“著名”的几个实现类。

  • ArrayList类:动态数组。
  • LinkedList:双向链表,JDK1.6之后又实现了双端队列Deque接口。
  • Vector类:动态数组。
  • Stack类:堆栈/

1.3.1 ArrayList类

  ArrayList类是使用最频繁的List集合类之一,它其实就是我们之前反复提到的动态数组的实现,因此它底层的物理结构是数组。

  之前使用的数组是静态分配空间,一旦分配了空间大小,就不可再改变;而动态数组是动态分配空间,随着元素的不断插入,它会按照自身的一套机制不断扩充自身的容量。动态数组扩容并不是在原有连续的内存空间后进行简单的叠加,而是重新申请一块更大的新内存,并把现有容器中的元素逐个赋值过去,然后销毁旧的内存。

  在构建ArrayList集合对象时,如果没有显示指定容量,那在JDK1.6及其之前版本的内部数组初始化容量默认为10,之后的版本初始化容量为长度为0的空数组,在添加第一个元素时再创建一个长度为10的数组。ArrayList延迟创建长度为10的数组的目的是节省内存空间,因为有时我们在创建ArrayList集合对象后,并没有添加元素,这点在方法的返回值类型是List类型时,极有可能存在。当然你也可以在创建ArrayList集合对象时,自己指定初始化容量。

  ArrayList类在添加一个新元素时,如果现有的数组容量不够,则会将新数组长度扩容为原来的1.5倍之后再添加。如果调用​​addAll​​方法一次添加多个元素,则会先判断原有数组是否够装,如果不够,则判断1.5倍容量是否够装,如果不够,就按实际需要来扩容数组。

1.3.2 LinkedList类

  LinkedList类是典型的双向链表的实现类,除可以实现List接口的方法,还为在列表的开头及结尾get(获取)、remove(移除)和insert(插入)元素提供了统一的命名方法。这些操作允许将链表用作堆栈、队列或双端队列。

  将LinkedList类作为普通列表形式使用的示例代码。

public class LinkedListTest1 {
public static void main(String[] args) {
LinkedList<Object> list = new LinkedList<>();
list.add(1);
list.add(2);
list.add(3);
list.add(4);
list.add(5);
for (Object o : list) {
System.out.println(o);
}
}
}

List集合_集合_06

  JDK1.6之后LinkedList类实现了Deque接口。双端队列也可用作LIFO(后进先出)堆栈。如果要使用堆栈的集合,那么可以考虑使用LinkedList类,而不是Deque接口,如下表所示。

堆栈方法

等效Deque方法

push(e)

addFirst(e)

pop()

removeFirst()

peek()

peekFirst()

  将LinkedList类作为堆栈使用的示例代码:

public class LinkedListTest2 {
public static void main(String[] args) {
LinkedList<Object> list = new LinkedList<>();
//入栈
list.addFirst(1);
list.addFirst(2);
list.addFirst(3);

//出栈:LIFO(后进先出)
System.out.println(list.removeFirst());
System.out.println(list.removeFirst());
System.out.println(list.removeFirst());
//栈空了,会报异常java.util.NoSuchElementException
System.out.println(list.removeFirst());
}
}

List集合_集合_07

  LinkedList类用作队列时,将得到FIFO(先进先出)行为,将元素添加到双端队列的末尾,从双端队列的开头移除元素,LinkedList类作为队列使用的方法如下表所示。

Queue方法

等效Deque方法

add(e)

addLast(e)

offer(e)

offerLast(e)

remove()

removeFirst()

poll()

pollFirst()

element()

getFirst()

peek()

peekFirst()

  将LinkedList类作为队列使用的示例代码:

import java.util.LinkedList;

public class LinkListTest3 {
public static void main(String[] args) {
LinkedList<Object> list = new LinkedList<>();
//入队
list.add(1);
list.add(2);
list.add(3);

//出队,FIFO(先进先出)
System.out.println(list.pollFirst());
System.out.println(list.pollFirst());
System.out.println(list.pollFirst());
//队列空了,返回Null
System.out.println(list.pollFirst());
}
}

List集合_java_08

  每种方法都存在两种形式:一种形式在操作失败时抛出异常,另一种形式则会返回一个特殊值,null或false,具体形式取决于操作,LinkedList类作为双向链表使用的方法如下所示。

第一个元素(头部)

最后一个元素(尾部)

抛出异常

特殊值

抛出异常

特殊值

插入

addFirst(e)

offerFirst(e)

addLast(e)

offerLast(e)

移除

removeFirst()

pollFirst()

removeLast()

pollLast()

检查

getFirst()

peekFirst()

getLast()

peekLast()

1.3.3 Vector类

  Vector类是STL(标准模板库)中最常见的容器,也是动态数组数据结构的实现。关于Vector类和ArrayList类两种动态数组的对比,如下表所示。


底层结构

初始化容量

扩容机制

线程安全(同步)

版本

效率

Vector类

动态数组

如果没有显示指定容量,则创建对象时,初始化容量为0

2倍

安全(同步)

较老

较低

ArrayList类

动态数组

如果没有显示指定容量,则在JDK6版本创建对象时,初始化容量为10,在更高版本创建对象时,初始化容量为0,第一次添加元素时,初始化容量为10.

1.5倍

不安全(不同步)

较新

较高

1.3.4 Stack类

  Stack类是Vector的子类,用于表示后进后出(LIFO)的对象堆栈,通过5个操作对Vector类进行了扩展,下表列出了Stack类具有堆栈特点的操作。

方法

功能解释

push(Object e)

将对象插入Stack类的顶部

Object peek()

返回位于Stack类顶部的对象但不将其移除

Object pop()

移除并返回位于Stack类顶部的对象

boolean empty()

堆栈是否为空

int search(Object o)

对象到堆栈顶部的位置,以1为基数;返回值-1则表示此对象不在堆栈中

import java.util.EmptyStackException;
import java.util.Stack;

public class StackTest {
//添加新元素到栈,即把新元素压入栈,成为新的栈顶元素
static void showPush(Stack st,Object value){
st.push(value);
System.out.println("push("+value+")");
System.out.println("现在栈顶元素是:"+st.peek());//查看当前栈顶元素
System.out.println("现在栈中的元素有:"+st);
}

//弹出当前栈顶元素,下一个元素称为新的栈顶元素
static void showPop(Stack st){
System.out.println("pop->"+st.pop());
System.out.println("现在栈中元素有:"+st);
}
public static void main(String[] args) {
Stack<Object> st = new Stack<>();
showPush(st,42);
showPush(st,66);
showPush(st,99);
showPop(st);
showPop(st);
showPop(st);
try {
showPop(st);
} catch (EmptyStackException e) {
// e.printStackTrace();
System.out.println("empty stack");
}
}
}

List集合_List_09

1.4 List集合的遍历

  因为List集合也属于Collection系列的集合,此前Collection集合支持的foreach遍历和Iterator遍历对于List集合来说仍然适用,这里就不再重复,下面介绍List集合的其他遍历方式。

1.4.1 普通for遍历循环遍历(效率不高)

public class ListForTest {
public static void main(String[] args) {
ArrayList<Student> list = new ArrayList<>();
list.add(new Student(1,"张三"));
list.add(new Student(2,"李四"));
list.add(new Student(3,"王五"));
list.add(new Student(4,"赵六"));
list.add(new Student(5,"钱七"));

for (int i = 0; i < list.size(); i++) {
System.out.println(list.get(i));
}

}
}

List集合_System_10

1.4.2 ListIterator迭代器

  List集合额外提供了一个​​listIterator()​​方法,该方法返回ListIterator对象,ListIterator接口继承了Iterator接口,提供了专门操作List的方法,如下所示。

  • ​void add()​​:通过迭代器添加元素到对应集合。
  • ​void set(Object obj)​​:通过迭代器替换正在迭代的元素。
  • ​void remove()​​:通过迭代器删除刚才迭代的元素。
  • ​boolean hasPrevious()​​:如果逆向遍历列表,则判断往前是否还有元素。
  • ​Object previous()​​:返回列表中的前一个元素。
  • ​int previousIndex()​​:返回列表中的前一个元素的索引。
  • ​boolean hasNext()​​:判断有没有下一个元素。
  • ​Object next()​​:返回列表中的最后一个元素。
  • ​int nextIndex()​​:返回列表中后一个元素的索引。
public class ListIteratorTest {
public static void main(String[] args) {
ArrayList<Object> c = new ArrayList<>();
c.add(new Student(1,"张三"));
c.add(new Student(2,"李四"));
c.add(new Student(3,"王五"));
c.add(new Student(4,"赵六"));
c.add(new Student(5,"钱七"));

//从指定位置往前遍历
ListIterator<Object> listIterator = c.listIterator(c.size());
while (listIterator.hasPrevious()){
Object previous = listIterator.previous();
System.out.println(previous);
}
}
}

List集合_List_11

1.4.3 foreach循环遍历

import java.util.ArrayList;

public class ListForTest {
public static void main(String[] args) {
ArrayList<Student> list = new ArrayList<>();
list.add(new Student(1,"张三"));
list.add(new Student(2,"李四"));
list.add(new Student(3,"王五"));
list.add(new Student(4,"赵六"));
list.add(new Student(5,"钱七"));

for (Student student : list) {
System.out.println(student);
}
}
}

List集合_java_12

1.4.4 Iterator迭代器遍历

public class ListForTest {
public static void main(String[] args) {
ArrayList<Student> list = new ArrayList<>();
list.add(new Student(1,"张三"));
list.add(new Student(2,"李四"));
list.add(new Student(3,"王五"));
list.add(new Student(4,"赵六"));
list.add(new Student(5,"钱七"));
Iterator<Student> iterator = list.iterator();
while(iterator.hasNext()){
Student next = iterator.next();
System.out.println(next);
}
}
}

List集合_java_13


标签:List,ArrayList,元素,list,add,集合,new
From: https://blog.51cto.com/u_15961549/6054226

相关文章

  • redis命令操作list和set&sortedset以及通用命令
    列表类型list:可以添加一个元素到列表的头部(左边)或者尾部(右边) 1.添加: 1.lpushkeyvalue:将元素加入列表左表 2.rpushkeyvalue:将元素加入列表右边 ......
  • uni-app:使用uni-list显示列表数据之一(hbuilderx 3.6.18)
    一,演示代码:说明:演示代码中实现的功能:    1,各个列表项展示不同类型的内容    2,取消uni-list-item默认样式中的padding    3,  取消uni-list......
  • jQuery遍历List对象
    jQuery遍历List对象在​​jQuery​​​中,可以使用​​each()​​​方法以一种非常直观的方式来模拟​​break​​​和​​continue​​​关键字的功能。只需在回调函数中编......
  • Arrays.asList报错:java.lang.UnsupportedOperationException
    问题描述以下代码中,给List对象添加元素的时候,会报错packagecom.example;importjava.util.Arrays;importjava.util.List;publicclassDemo{publicstaticvoidmain......
  • DataTable转换泛型List 帮助类
    usingSystem;usingSystem.Collections.Generic;usingSystem.Data;usingSystem.Linq;usingSystem.Reflection;namespaceJNPF.Common.Security{///<summary>......
  • JSON解析器Jackson_java对象转json_List&Map与Json转java对象
    1.复杂java对象转换1.List:数组2.Map:对象格式一致packageorg.example.text;importcom.fasterxml.jackson.databind.ObjectMapper;importorg.example.dom......
  • Java中object转list
    java/***object转list**@paramobj*@paramclazz*@param<T>*@return*/publicstatic<T>List<T>castList(Objec......
  • C语言:最小公倍数 方法集合
    //求最小公倍数//两个或多个整数公有的倍数叫做它们的公倍数,其中除0以外最小的一个公倍数就叫做这几个整数的最小公倍数。#include<stdio.h>main(){intm,n,i,......
  • C语言:判断质数方法集合
    #include<stdio.h>intmain(){intm,i,count=0;//定义一个正整数m,因子i,因子计数count,刚开始因子为0;printf("请输入一个正整数:\n");scanf("%d",&m);......
  • java: 小王子单链表 ------ ( LinkedList )
    java.util包中的LinkedList<E>泛型类创建的对象以链表结构存储数据,习惯上称LinkedList类创建的对象为链表对象。LinkedList<String>myList=newLinkedList<String>(......