【Java集合】List接口常用方法及实现子类
创始人
2024-03-05 01:48:27
0

文章目录

  • List接口
    • > List 接口的常用方法
    • > List的三种遍历方式
    • > List 排序练习
      • ※ ArrayList 使用注意事项
      • ※ ArrayList 底层结构
      • ※ Vector 底层结构
      • ※ LinkedList 底层结构 (双向链表和增删改查案例)
    • > ArrayList 和 LinkedList 比较

List接口

在这里插入图片描述

  • List集合类中元素有序(即添加和取出顺序一致),且可重复
  • List集合中的每个元素都有其对应的顺序索引,即支持索引;
  • List容器中的元素都对应一个整数型的序号记其在容器中的位置,可以根据序号存取容器中的元素
  • List常用接口有 ArrayList、LinkedList、Vector
//1.List集合类中元素有序(即添加和取出顺序一致),且可重复List list = new ArrayList();list.add("Jack");list.add("Tom");list.add("Marry");list.add("Marry");System.out.println(list);//[Jack, Tom, Marry, Marry]取出输出顺序和存放顺序一致,且可重复//2.List集合中的每个元素都有其对应的顺序索引,即支持索引System.out.println(list.get(2));//Marry//3.List容器中的元素都对应一个整数型的序号记其在容器中的位置,可以根据序号存取容器中的元素

> List 接口的常用方法

  1. void add (int index,Object ele) :在index位置插入ele元素;
  2. boolean addAll (int index,Collection eles) :从index位置开始将eles集合中的所有元素添加进来;
  3. Object get (int index) :获取指定index位置的元素;
  4. int indexOf (Object obj) :返回obj在集合中首次出现的位置;
  5. int lastIndexOf (Object obj) :返回obj在集合中末次出现的位置;
  6. Object remove (int index) :移除指定index位置的元素,并返回此元素;
  7. Object set (int index,Object ele) :设置指定index的位置的元素为ele,相当于是替换;
  8. List subList (int fromIndex,int toIndex) :返回从fromIndex到toIndex位置的子集合;

更多方法可以自行JDK API在线查询下载中文版JavaAPI帮助文档【免费0积分下载】

//向上转型,用List来接收ArrayList
List list = new ArrayList();//1. void add (int index,Object ele) :在index位置插入ele元素;
list.add("开心的你");
list.add(0,"帅气的我");//在0位置插入
System.out.println(list);//[帅气的我, 开心的你]//2. boolean addAll (int index,Collection eles) :从index位置开始将eles集合中的所有元素添加进来;
List list1 =  new ArrayList();
list1.add("Jack");list1.add("Tom");list1.add("Marry");
list.addAll(1,list1);
System.out.println(list);//[帅气的我, Jack, Tom, Marry, 开心的你]//3. Object get (int index) :获取指定index位置的元素;
System.out.println(list.get(0));//帅气的我//4. int indexOf (Object obj) :返回obj在集合中首次出现的位置;
System.out.println(list.indexOf("开心的你"));//4//5. int lastIndexOf (Object obj) :返回obj在集合中末次出现的位置;
list.add("Jack");
System.out.println(list.lastIndexOf("Jack"));//5//6. Object remove (int index) :移除指定index位置的元素,并返回此元素;
System.out.println(list.remove(5));//Jack
System.out.println(list);//[帅气的我, Jack, Tom, Marry, 开心的你]//7. Object set (int index,Object ele) :设置指定index的位置的元素为ele,相当于是替换;
list.set(1,"!!!");
System.out.println(list);//[帅气的我, !!!, Tom, Marry, 开心的你]//8. List subList  (int fromIndex,int toIndex) :返回从fromIndex到toIndex位置的子集合;
//返回的子集合: [fromIndex,toIndex) 左闭右开
System.out.println(list.subList(2,4));//[Tom, Marry]

> List的三种遍历方式

import java.util.*;public class ListFor {public static void main(String[] args) {//List的实现接口子类ArrayList LinkedList Vector//List list = new ArrayList();//List list = new LinkedList();List list = new Vector();list.add("熊大");list.add("熊二");list.add("光头强");//迭代器iterator遍历Iterator iterator = list.iterator();while(iterator.hasNext()){Object next = iterator.next();System.out.println(next);}//增强for遍历for (Object o:list) {System.out.println(o);}//普通遍历for (int i=0;iSystem.out.println(list.get(i));}}
}

> List 排序练习

import java.util.ArrayList;
import java.util.List;public class Demo {public static void main(String[] args) {//List list = new ArrayList();//List list = new LinkedList();List list = new Vector();list.add(new Book("红楼梦", 36.4f, "曹雪芹"));list.add(new Book("水浒传", 19.9f, "施耐庵"));list.add(new Book("西游记", 28.8f, "吴承恩"));//遍历for(Object o:list){System.out.println(o);}//冒泡排序sort(list);System.out.println("---- 排序后 ----");for(Object o:list){System.out.println(o);}}//静态方法:冒泡排序//要求价格从小到大public static void sort(List list){for (int i=0;ifor (int j=0;j//取出对象bookBook book1 = (Book) list.get(j);Book book2 = (Book) list.get(j+1);if(book1.getPrice()>book2.getPrice()){//交换list.set(j,book2);list.set(j+1,book1);}}}}
}
class Book{private String name;private float price;private String author;@Overridepublic String toString() {return "书名: "+name+"  价格: "+price+"  作者: "+author;}public Book(String name, float price, String author) {this.name = name;this.price = price;this.author = author;}public void setName(String name) {this.name = name;}public void setPrice(float price) {this.price = price;}public void setAuthor(String author) {this.author = author;}public String getName() {return name;}public float getPrice() {return price;}public String getAuthor() {return author;}
}

※ ArrayList 使用注意事项

  • 允许存放任何元素,包括空元素null
ArrayList list = new ArrayList();
list.add(null);
list.add("OK");
list.add(null);
System.out.println(list);
//[null,OK,null]
  • ArrayList 是由数组来实现数据存储的;
  • ArrayList基本等同于 Vector ,除了 ArrayList是线程不安全的,但执行效率高,在多线程的情况下不建议用ArrayList

※ ArrayList 底层结构

  • ArrayList中维护了一个Object类型的数组
    transient Object[ ] elementData; //transient 短暂的 表示该属性不会被序列化
  • 当创建ArrayList对象时,如果使用的是无参构造器,则初始elementData容量为0 ,第一次添加则扩容elementData为10,如需要再次扩容,则扩容elementData为1.5 倍;
  • 如果使用的是指定大小的构造器,则初始扩容elementData容量为指定大小,如果需要再次扩容,则直接扩容为1.5倍;

※ Vector 底层结构

  • Vector 底层也是一个对象数组,protected Object[ ] elementData;
  • Vector 是线程同步的,即线程安全,Vector类的操作方法带有synchronized
  • 在开发中,需要线程同步安全时,考虑使用Vector

※ LinkedList 底层结构 (双向链表和增删改查案例)

在这里插入图片描述

  • LinkedList 实现了双向链表和双端队列的特点
  • 可以添加任意元素(元素可以重复),包括null;
  • 线程不安全,没有实现同步
  • LinkedList底层维护了一个双向链表;
  • LinkedList中维护了两个属性first和last分别指向 首节点 和 尾节点;
  • 每个节点(Node对象),里面又维护了prev、next、item三个属性,其中通过prev指向前一个,通过next指向后一个节点,最终完成双向链表;
  • 所以 LinkedList的元素的添加和删除不是通过数组完成的,相对来说效率较高;

双向链表的模拟:

public class TestLinkedList01 {public static void main(String[] args) {//模拟一个简单的双向链表Node jack = new Node("Jack");Node tom = new Node("Tom");Node marry = new Node("Marry");//连接三个节点,形成双向链表//jack -> tom -> marryjack.next = tom;tom.next = marry;//jack <- tom <- marrymarry.pre = tom;tom.pre = jack;Node first = jack;//让first引用指向jack,就是双向链表的首节点Node last = marry;//让last引用指向marry,就是双向链表的尾节点//演示 从头到尾 遍历System.out.println("--------- 从头到尾的遍历 --------");while(true){if(first == null){break;}//输出first信息System.out.println(first);first = first.next;//输出完以后,first指向下一个/*Node name = JackNode name = TomNode name = Marry进程已结束,退出代码0*/}//从尾到头的遍历System.out.println("--------- 从尾到头遍历 --------");while(true){if(last == null){break;}//输出last信息System.out.println(last);last = last.pre;//输出完以后,first指向下一个/*Node name = MarryNode name = TomNode name = Jack*/}//演示链表的添加对象/数据//在tom和marry之间插入一个对象//1.先创建一个Node节点,name为smithNode smith = new Node("Smith");//2.把smith加入双向链表smith.next = marry;smith.pre = tom;marry.pre = smith;tom.next = smith;//3.让first再次指向jackfirst =  jack;//演示 从头到尾 遍历System.out.println("--------- 插入smith后 从头到尾的遍历 --------");while(true){if(first == null){break;}//输出first信息System.out.println(first);first = first.next;//输出完以后,first指向下一个}/*Node name = JackNode name = TomNode name = SmithNode name = Marry*/}}//定义一个Node类,Node对象表示双向链表的一个节点
class Node{public Object item;//真正存放数据的地方public Node next;//指向下一个节点public Node pre;//指向前一个节点public Node(Object name){this.item  = name;}public String toString(){return "Node name = "+item;}
}

LinkedList的增删改查案例:

import java.util.Iterator;
import java.util.LinkedList;public class LinkListCRUD {public static void main(String[] args) {LinkedList linkedList = new LinkedList();//增linkedList.add(1);//size=0添加一个新节点,首尾指针都指向这个新节点linkedList.add(2);//last指向新节点,first还是指向第一个节点,next指向新节点linkedList.add(3);System.out.println("增后: "+linkedList);//删linkedList.remove();//默认删除第一个System.out.println("删后: "+linkedList);//就是去掉指针//改linkedList.set(1,999);System.out.println("改后: "+linkedList);//查//get(1) 得到双向链表的第二个对象Object o = linkedList.get(1);System.out.println(o);//999//因为LinkedList是实现了List接口,所以遍历方式:Iterator iterator = linkedList.iterator();while (iterator.hasNext()) { //快捷输入ititObject next =  iterator.next();System.out.println(next);}//还有增强for 和普通for 遍历}
}

(可以自行debug看一下调用方法的实现)


> ArrayList 和 LinkedList 比较

集合底层结构增删的效率改查的效率
ArrayList可变数组较低,数组扩容较高
LinkedList双向链表较高,通过链表追加较低

如何选择 ArrayList 和 LinkedList :

  1. 如果改查的操作较多,选择 ArrayList;
  2. 如果增删的操作较多,选择 LinkedList;
  3. 一般程序中,80%-90%都是查询,因此大部分会使用ArrayList;
  4. 在项目中,灵活选择,可以一个模块用LinkedList,一个模块用ArrayList;

多线程的情况还是考虑 Vector ,因为它是线程安全的

相关内容

热门资讯

AWSECS:访问外部网络时出... 如果您在AWS ECS中部署了应用程序,并且该应用程序需要访问外部网络,但是无法正常访问,可能是因为...
AWSElasticBeans... 在Dockerfile中手动配置nginx反向代理。例如,在Dockerfile中添加以下代码:FR...
银河麒麟V10SP1高级服务器... 银河麒麟高级服务器操作系统简介: 银河麒麟高级服务器操作系统V10是针对企业级关键业务...
北信源内网安全管理卸载 北信源内网安全管理是一款网络安全管理软件,主要用于保护内网安全。在日常使用过程中,卸载该软件是一种常...
AWR报告解读 WORKLOAD REPOSITORY PDB report (PDB snapshots) AW...
AWS管理控制台菜单和权限 要在AWS管理控制台中创建菜单和权限,您可以使用AWS Identity and Access Ma...
​ToDesk 远程工具安装及... 目录 前言 ToDesk 优势 ToDesk 下载安装 ToDesk 功能展示 文件传输 设备链接 ...
群晖外网访问终极解决方法:IP... 写在前面的话 受够了群晖的quickconnet的小水管了,急需一个新的解决方法&#x...
不能访问光猫的的管理页面 光猫是现代家庭宽带网络的重要组成部分,它可以提供高速稳定的网络连接。但是,有时候我们会遇到不能访问光...
Azure构建流程(Power... 这可能是由于配置错误导致的问题。请检查构建流程任务中的“发布构建制品”步骤,确保正确配置了“Arti...