List接口和常用方法

本文介绍了List接口在Java中的核心概念,包括有序性、索引操作、常用方法(如添加、获取、查找、删除和设置)以及ArrayList、LinkedList和Vector的使用。还对比了ArrayList和LinkedList在增删查改上的区别,以及不同场景下的选择建议。
摘要由CSDN通过智能技术生成

List接口基本介绍

List接口是Collection接口的子接口

  1. List集合类中元素有序(即添加顺序和取出顺序一致)、 且可重复

  2. List集合中的每个元素都有其对应的顺序索引,即支持索引。

  3. List容器中的元素都对应一个整数型的序号记载其在容器中的位置,可以根
    据序号存取容器中的元素。

  4. JDK API中List接口的实现类有:

请添加图片描述

常用的有: ArrayList、 LinkedList和Vector.

package www.xz.list_;

import java.util.ArrayList;
import java.util.List;

/**
 * @author 许正
 * @version 1.0
 */
public class List_ {
    @SuppressWarnings({"all"})
    public static void main(String[] args) {

        List list = new ArrayList();

        list.add("tom");
        list.add("jack");
        list.add("milan");
        list.add("zeaper");
        list.add("xz");
        list.add("tom");

        System.out.println("list=" + list);
        //索引下标从0开始
        System.out.println(list.get(3));
    }
}

List接口和常用方法

●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 tolndex):返回从fromIndex到 toIndex位置的子集合
package www.xz.list_;

import java.util.ArrayList;
import java.util.List;

/**
 * @author 许正
 * @version 1.0
 */
public class ListMethod {
    public static void main(String[] args) {
        @SuppressWarnings({"all"})
        List list = new ArrayList();
        list.add("张三丰");
        list.add("贾宝玉");

//        1) void add(int index, Object ele):在index位置插入ele元素
        //在 index=1 的位置插入 许正  ,如果index位置不填默认添加到最后
        list.add(1, "许正");
        System.out.println("list=" + list);

//        2) boolean addAll(int index, Collection eles):从index位置开始将eles中的所有元素添加进来
        List list2 = new ArrayList();
        list2.add("jack");
        list2.add("tom");
        list.addAll(1, list2);
        System.out.println("list=" + list);
//        3) Object get(int index):获取指定index位置的元素
        System.out.println(list.get(3));
//        4) int indexOf(Object obj):返回obj在集合中首次出现的位置
        list.add("tom");
        System.out.println(list.indexOf("tom"));//2
//        5) int lastIndexOf(Object obj):返回obj在当前集合中末次出现的位置
        System.out.println(list);
        System.out.println(list.lastIndexOf("tom"));//5
//        6) Object remove(int index):移除指定index位置的元素,并返回此元素
//        list.remove("tom");
        list.remove(5);
        System.out.println("list=" + list);
//        7) Object set(int index, Object ele):设置指定index位置的元素为ele  相当于是替换.
        list.set(3, "zeaper");
        System.out.println("list=" + list);
//        8) List subList(int fromIndex, int toIndex):返回从fromIndex到 toIndex位置的子集合
        //注意:  左闭右开!
        List subList = list.subList(1, 4);
        System.out.println("sublist=" + subList);
    }
}

List的三种遍历方式[ArrayList, LinkedList, Vector]

1)方式一:使用iterator

Iterator iter = col.iterator();
while(iter.hasNext(){
	Object 0 = iter.next(); 
}

2)方式二:使用增强for

for(Object o:col){
}

3)方式三:使用普通for

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

说明:使用LinkedList完成使用方式和ArrayList一样

ArrayList底层结构和源码分析

●ArrayList的注意事项

  1. permits all elements, including null , ArrayList可以加入null,并且多个
  1. ArrayList是由数组来实现数据存储的
  2. ArrayList基本等同于Vector,除了ArrayList是线程不安全(执行效率高)看源码.
    在多线程情况下,不建议使用ArrayList

●ArrayList的底层操作机制源码分析(重点,难点.)

  1. ArrayList中维护了一个Object类型的数组elementData.

transient Object[] elementData;

  1. 当创建ArrayList对象时,如果使用的是无参构造器,则初始elementData容量为0,第1
    次添加,则扩容elementData为10,如需要再次扩容,则扩容elementData为1. 5倍。
  2. 如果使用的是指定大小的构造器,则初始elementData容量为指定大小,如果需要扩容,
    则直接扩容elementData为1.5倍。
package www.xz.list_;

import java.util.ArrayList;

/**
 * @author 许正
 * @version 1.0
 */
@SuppressWarnings({"all"})
public class ArrayListSource {
    public static void main(String[] args) {
//        ArrayList list = new ArrayList();
        ArrayList list = new ArrayList(8);

        for (int i = 1; i <= 10; i++) {
            list.add(i);
        }

        for (int i = 11; i <= 15; i++) {
            list.add(i);
        }

        list.add(100);
        list.add(200);
        list.add(null);
//        System.out.println(list);
        for (Object o : list) {
            System.out.println(o);
        }
    }
}

Vector底层结构和源码剖析

●Vector的基本介绍

  1. Vector类的定义说明

请添加图片描述

  1. Vector底层也是一个对象数组,protected Object[] elementData;

  2. Vector是线程同步的,即线程安全,Vector类的操作方法带有synchronized

public synchronized E get(int index) {
	if (index >= elementCount)
		throw new ArrayIndexOutOfBoundsException(index);
	return elementData(index);
}
  1. 在开发中,需要线程同步安全时,考虑使用Vector
package www.xz.list_;

import java.util.Vector;

/**
 * @author 许正
 * @version 1.0
 */
public class Vector_ {
    public static void main(String[] args) {
        Vector vector = new Vector();
        for (int i = 0; i < 10; i++) {
            vector.add(i);
        }
    }
}

Vector和ArrayList的比较

请添加图片描述

LinkedList的全面说明

  1. LinkedList底层实现了双向链表和双端队列特点
  2. 可以添加任意元素(元素可以重复),包括null
  3. 线程不安全,没有实现同步

LinkedList底层结构

●LinkedList的底层操作机制

  1. LinkedList底层维护了一个双向链表
  2. LinkedList中维护了两个属性first和last分别指向首节点和尾节点
  3. 每个节点(Node对象) ,里面又维护了prev、next、 item三个属性,其中通过
    prev指向前一个, 通过next指向后一个节点。最终实现双向链表.
  4. 所以LinkedList的元素的添加和删除,不是通过数组完成的,相对来说效率较高。
  5. 模拟一个简单的双向链表
package www.xz.list_;

/**
 * @author 许正
 * @version 1.0
 */
public class LinkedList01 {
    public static void main(String[] args) {
        //模拟一个双向链表

        Node jack = new Node("jack");
        Node tom = new Node("tom");
        Node xz = new Node("许正");

        //连接三个结点,形成双向链表
        //jack -> tom -> xz
        jack.next = tom;
        tom.next = xz;
        //xz -> tom -> jack
        xz.pre = tom;
        tom.pre = jack;

        Node first = jack;// 让first引用指向jack,就是双向链表的头结点
        Node last = xz;//让Last引用指向hsp,就是双向链表的尾结点

        System.out.println("从头到尾进行遍历:");
        //演示:从头到尾进行遍历
        while (true) {
            if (first == null) {
                break;
            }
            //输出first 信息
            System.out.println(first);
            first = first.next;
        }

        System.out.println("从尾到头进行遍历:");
        //演示:从尾到头进行遍历
        while (true) {
            if (last == null) {
                break;
            }
            //输出last 信息
            System.out.println(last);
            last = last.pre;
        }


        //演示链表的添加对象/数据,是多么的方便
        //要求,是在 tom --- xz 之间直接,插入一个对象 smith
        Node smith = new Node("smith");
        smith.next = xz;
        smith.pre = tom;
        xz.pre = smith;
        tom.next = smith;

        //再次遍历
        //让first重新指向第一个对象(jack)
        first = jack;
        System.out.println("添加信息之后再次进行遍历:");
        while (true) {
            if (first == null) {
                break;
            }
            System.out.println(first);
            first = first.next;
        }

        //重新进行从尾到头遍历
        System.out.println("重新进行从尾到头遍历:");
        last = xz;
        while (true) {
            if (last == null) {
                break;
            }
            System.out.println(last);
            last = last.pre;
        }
    }
}

//定义一个Node类,Node 对象表示双向链表的一个结点
class Node {
    public Object item;//真正存放数据
    public Node next;//指向后一个结点
    public Node pre;//指向前一个结点

    public Node(Object item) {
        this.item = item;
    }

    @Override
    public String toString() {
        return "Node name=" + item;
    }
}

●LinkedList的增删改查案例

追源码会理解的更加透彻!!!

package www.xz.list_;

import java.util.Iterator;
import java.util.LinkedList;

/**
 * @author 许正
 * @version 1.0
 */
@SuppressWarnings({"all"})
public class LinkedListCRUD {
    public static void main(String[] args) {
        LinkedList linkedList = new LinkedList();
        linkedList.add(1);
        linkedList.add(2);
        linkedList.add(3);

        System.out.println("linkedList=" + linkedList);

        //演示删除节点:
        //删除第一个结点:
        linkedList.remove();
//        linkedList.remove(1);
        System.out.println(linkedList);

        //修改某个结点对象
        linkedList.set(1, 999);
        System.out.println(linkedList);

        //得到某个对象
        //get(1)指的是得到双向链表中第二个对象
        System.out.println(linkedList.get(1));

        //因为 LinkedList 实现了 List 接口,所以 增强for 和 迭代器 都可以使用
        for (Object o : linkedList) {
            System.out.println("o=" + o);
        }

        Iterator iterator = linkedList.iterator();
        while (iterator.hasNext()) {
            Object next = iterator.next();
            System.out.println("next=" + next);
        }

        System.out.println("====普通for循环====");
        for (int i = 0; i < linkedList.size(); i++) {
            System.out.println(linkedList.get(i));
        }
    }
}

ArrayList和LinkedList的比较

请添加图片描述

如何选择ArrayList和LinkedList:

  1. 如果我们改查的操作多,选择ArrayList
  2. 如果我们增删的操作多,选择LinkedList
  3. 一般来说,在程序中,80%-90%都是查询,因此大部分情况下会选择ArrayList
  4. 在一个项目中,根据业务灵活选择,也可能这样,一个模块使用的是ArrayList,另
    外一个模块是LinkedList,也就是说,要根据业务来进行选择

这两个集合都是单线程的!不安全!!!无并发情况下进行两个之间的选择。

ListExercise 两个练习

package www.xz.list_;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

/**
 * @author 许正
 * @version 1.0
 */
public class ListExercise {
    public static void main(String[] args) {
//        添加10个以上的元素(比如String "hello" ),在2号位插入一个元素"许正",
//        获得第5个元素,删除第6个元素,修改第7个元素,在使用迭代器遍历集合,
//        要求:使用List的实现类ArrayList完成。
        List list = new ArrayList();
        for (int i = 0; i < 12; i++) {
            list.add("hello" + i);
        }
        System.out.println(list);

        list.add(2, "许正");
        System.out.println(list);
        System.out.println(list.get(4));
        list.remove(5);
        System.out.println(list);
        list.set(6, "zeaper");

        Iterator iterator = list.iterator();
        while (iterator.hasNext()) {
            Object next = iterator.next();
            System.out.println("next=" + next);
        }

    }
}
package www.xz.list_;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Vector;

/**
 * @author 许正
 * @version 1.0
 */
@SuppressWarnings({"all"})
public class ListExercise02 {
    public static void main(String[] args) {

        List list = new ArrayList();
//        List list = new Vector();
//        List list = new LinkedList();
        list.add(new Book("红楼梦", "曹雪芹", 100));
        list.add(new Book("西游记", "吴承恩", 10));
        list.add(new Book("水浒传", "施耐庵", 19));
        list.add(new Book("三国演义", "罗贯中", 80));
//        list.add(new Book("西游记", "吴承恩", 100));

        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; i < list.size() - 1; i++) {
            for (int j = 0; j < list.size() - 1 - i; j++) {
                //取出对象Book
                Book 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 String author;
    private int price;

    public Book(String name, String author, int price) {
        this.name = name;
        this.author = author;
        this.price = price;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getAuthor() {
        return author;
    }

    public void setAuthor(String author) {
        this.author = author;
    }

    public int getPrice() {
        return price;
    }

    public void setPrice(int price) {
        this.price = price;
    }

    @Override
    public String toString() {
        return "名称:" + name + "\t\t价格:" + price + "\t\t作者:" + author;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序员正正

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值