42、集合的第一大类:List

一、基本介绍:

1、List接口和常用方法

(1)List接口基本介绍:

List接口是Collection接口的子接口

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

2)List集合中每个元素都有其对应的顺序索引,即支持索引(索引从0开始)

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

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

 其中常用的有:ArrayList, LinkedList和Vector

 ·注意:subList()返回的是[fromIndex, toIndex)

5)

 //我的代码:

package Collection_;

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

public class List01 {
    @SuppressWarnings({"all"})
    public static void main(String[] args) {
        List list=new ArrayList<>();
        list.add("hello");
        list.add("hello");
        list.add("hello");
        list.add("hello");
        list.add("hello");
        list.add("hello");
        list.add("hello");
        list.add("hello");
        list.add("hello");
        list.add("hello");
        System.out.println("list="+list);
        list.set(2,"韩顺平教育");
        System.out.println("list="+list);
        System.out.println("list的第5个元素是:"+list.get(5));
        list.remove(6);
        list.set(7,"hi");
        System.out.println("=======使用迭代器遍历list=========");
        Iterator iterator=list.iterator();
        while (iterator.hasNext()) {
            Object next =  iterator.next();
            System.out.println(next);
        }
    }
}
//list=[hello, hello, hello, hello, hello, hello, hello, hello, hello, hello]
//list=[hello, hello, 韩顺平教育, hello, hello, hello, hello, hello, hello, hello]
//list的第5个元素是:hello
//=======使用迭代器遍历list=========
//hello
//hello
//韩顺平教育
//hello
//hello
//hello
//hello
//hi
//hello

//老师的代码:

package Collection_;

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

public class ListExercise01 {
    @SuppressWarnings({"all"})
    public static void main(String[] args) {
        List list=new ArrayList();
        for(int i=0;i<12;i++){
            list.add("hello"+i);
        }
        System.out.println("list="+list);
        list.add(1,"韩顺平教育");
        System.out.println("list="+list);
        System.out.println("第五个元素:"+list.get(4));
        list.remove(5);
        System.out.println("list="+list);
        list.set(6,"hi");
        System.out.println("list="+list);
        Iterator iterator=list.iterator();
        while (iterator.hasNext()) {
            Object obj =  iterator.next();
            System.out.println("obj="+obj);
        }
    }
}
//list=[hello0, hello1, hello2, hello3, hello4, hello5, hello6, hello7, hello8, hello9, hello10, hello11]
//list=[hello0, 韩顺平教育, hello1, hello2, hello3, hello4, hello5, hello6, hello7, hello8, hello9, hello10, hello11]
//第五个元素:hello3
//list=[hello0, 韩顺平教育, hello1, hello2, hello3, hello5, hello6, hello7, hello8, hello9, hello10, hello11]
//list=[hello0, 韩顺平教育, hello1, hello2, hello3, hello5, hi, hello7, hello8, hello9, hello10, hello11]
//obj=hello0
//obj=韩顺平教育
//obj=hello1
//obj=hello2
//obj=hello3
//obj=hello5
//obj=hi
//obj=hello7
//obj=hello8
//obj=hello9
//obj=hello10
//obj=hello11

2、List的三种遍历方式:

 (1)

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

public class ListExercise02 {
    @SuppressWarnings({"all"})
    public static void main(String[] args) {
        List list=new ArrayList();
        //List list=new LinkedList();
        //List list=new Vector();
        list.add(new Book("红楼梦","曹雪芹",100));
        list.add(new Book("西游记","吴承恩",10));
        list.add(new Book("水浒传","施耐庵",9));
        list.add(new Book("三国演义","罗贯中",80));
        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){
        int listSize=list.size();
        for(int i=0;i<listSize-1;i++){
            for(int j=0;j<listSize-1-i;j++){
                Book book1=(Book) list.get(j);//卡在了如何取出对象Book是关键,使用向下转型
                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 bookName;
    private String author;
    private double price;

    public Book(String bookName, String author, double price) {
        this.bookName = bookName;
        this.author = author;
        this.price = price;
    }

    public String getBookName() {
        return bookName;
    }

    public void setBookName(String bookName) {
        this.bookName = bookName;
    }

    public String getAuthor() {
        return author;
    }

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

    public double getPrice() {
        return price;
    }

    public void setPrice(double price) {
        this.price = price;
    }
    public void bubbleSort(List list){
    }
    @Override
    public String toString() {
        return "名称:" + bookName + '\t' + "价格:" + price + '\t' + "作者:" + author;
    }
}
//名称:红楼梦	价格:100.0	作者:曹雪芹
//名称:西游记	价格:10.0	作者:吴承恩
//名称:水浒传	价格:9.0	作者:施耐庵
//名称:三国演义	价格:80.0	作者:罗贯中
//==================排序后===================
//名称:水浒传	价格:9.0	作者:施耐庵
//名称:西游记	价格:10.0	作者:吴承恩
//名称:三国演义	价格:80.0	作者:罗贯中
//名称:红楼梦	价格:100.0	作者:曹雪芹

3、ArrayList

(1)注意事项:

1) permits all elements, including null,ArrayList 可以加入null,并且多个

2)ArrayList是由数组来实现数据存储的

3)ArrayList 基本等同于Vector,除了ArrayList是线程不安全(执行效率高)看源码,

在多线程情况下,不建议使用ArrayList

(2)ArrayList的底层操作机制源码分析(重点,难点.)(B站第510集,还没有吃透)

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

transient Object[] elementData;  //transient表示瞬间、短暂的,表示该属性不会被序列化

2) 当创建对象时,如果使用的是无参构造器,则初始elementData容量为0(jdk7是10)

3) 当添加元素时:先判断是否需要扩容,如果需要扩容,则调用grow方法,否则直接添加元素到合适位置

4) 如果使用的是无参构造器,如果第一次添加,需要扩容的话,则扩容elementData为10,如果需要再次扩容的话,则扩容elementData为1.5倍。

5)如果使用的是指定容量capacity的构造器,则初始elementData容量为capacity

6)如果使用的是指定容量capacity的构造器,如果需要扩容,则直接扩容elementData为1.5倍。

4、Vector:

1) Vector类的定义说明

public class vector<E>
extends AbstractList<E>
implements List<E>, RandomAccess, Cloneable, Serializable

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

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

public synchronized E get(int index) (
if (index >= elementCount) 1
throw new ArraylndexOutOfBoundsException(index); return elementData(index);

4)在开发中,需要线程同步安全时,考虑使用Vector

5、LinkedList:

(1)基本介绍:

1)LinkedList底层实现了双向链表和双端队列特点

2)可以添加任意元素(元素可以重复),包括null

3)线程不安全,没有实现同步

(2)LinkedList的底层操作机制

1)LinkedList底层维护了一个双向链表.

2)LinkedList中维护了两个属性first和last分别指向 首节点和尾节点

3) 每个节点(Node对象),里面又维护了prev、next、item三个属性,其中通过prev指向前一个,通过next指向后一个节点,item用于存放数据。最终实现双向链表.

4)所以LinkedList的元素的添加和删除,不是通过数组完成的,相对来说效率较高。

5) 模拟一个简单的双向链表:

package Collection_;

public class LinkedList_ {
    public static void main(String[] args) {
        //模拟一个简单的双向链表
        Node jack=new Node("jack");
        Node tom=new Node("tom");
        Node hsp=new Node("老韩");

        //连接三个结点,形成双向链表
        jack.next=tom;
        tom.next=hsp;
        //hsp-->tom-->jack
        hsp.pre=tom;
        tom.pre=jack;
        Node first=jack;//让first引用指向jack,就是双向链表的头结点
        Node last=hsp;//让last引用指向hsp,就是双向链表的尾结点

        System.out.println("=====从头到尾进行遍历======");
        while(true){
            if(first==null){
                break;
            }
            System.out.println(first);
            first=first.next;
        }

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

        //添加一个对象,在tom和老韩之间直接插入一个对象smith
        Node smith=new Node("smith");
        smith.next=hsp;
        smith.pre=tom;
        hsp.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;
        }

        last=hsp;//让last再次指向hsp,就是双向链表的尾结点
        System.out.println("=====从尾到头进行遍历======");
        while(true){
            if(last==null){
                break;
            }
            System.out.println(last);
            last=last.pre;
        }
    }
}
class Node{
    public Object item;//真正存放数据
    public Node next;//指向后一个结点
    public Node pre;//指向前一个结点
    public Node(Object name){
        this.item=name;
    }

    @Override
    public String toString() {
        return "Node name="+item;
    }
}
//=====从头到尾进行遍历======
//Node name=jack
//Node name=tom
//Node name=老韩
//=====从尾到头进行遍历======
//Node name=老韩
//Node name=tom
//Node name=jack
//=====从头到尾进行遍历======
//Node name=jack
//Node name=tom
//Node name=smith
//Node name=老韩
//=====从尾到头进行遍历======
//Node name=老韩
//Node name=smith
//Node name=tom
//Node name=jack

补:CRUD:表示增删改查(create, read, update, delete)

6、ArrayList和LinkedList的比较

(2)如何选择ArrayList和LinkedList:

1)如果我们改查的操作多,选择ArrayList

2) 如果我们增删的操作多,选择LinkedList

3) 一般来说,在程序中,80%—90%都是查询,因此大部分情况下会选择ArrayList

4) 在一个项目中,根据业务灵活选择,也可能这样,一个模块使用的是ArrayList,另外一个模块是LinkedList.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

戏拈秃笔

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

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

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

打赏作者

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

抵扣说明:

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

余额充值