19--集合框架

发布时间:2023年12月18日

1、集合框架概述

1.1 数组的特点和弊端

一方面,面向对象语言对事物的体现都是以对象的形式,为了方便对多个对象的操作,就要对对象进行存储。另一方面,使用数组存储对象方面具有一些弊端,而Java 集合就像一种容器,可以动态地把多个对象的引用放入容器中。

数组在内存存储方面的特点:

  • 数组初始化以后,长度就确定了。
  • 数组中的添加的元素是依次紧密排列的,有序的,可以重复的。
  • 数组声明的类型,就决定了进行元素初始化时的类型。不是此类型的变量,就不能添加。
  • 可以存储基本数据类型值,也可以存储引用数据类型的变量

数组在存储数据方面的弊端:

  • 数组初始化以后,长度就不可变了,不便于扩展
  • 数组中提供的属性和方法少,不便于进行添加、删除、插入、获取元素个数等操作,且效率不高。
  • 数组存储数据的特点单一,只能存储有序的、可以重复的数据

Java 集合框架中的类可以用于存储多个对象,还可用于保存具有映射关系的关联数组。

1.2 什么是集合

集合:集合是Java中提供的一种容器,可以用来存储多个数据,并且可以存储任意类型的数据!

集合和数组既然都是容器,它们有啥区别呢?

  • 数组的长度是固定的。集合的长度是可变的。
  • 数组中存储的是同一类型的元素,可以存储基本数据类型值。
  • 集合存储的都是对象。而且对象的类型可以不一致,不能存放基本数据类型

1.3 Java集合框架体系

Java 集合可分为 Collection 和 Map 两大体系:

Collection接口:用于存储一个一个的数据,也称单列数据集合

????????List子接口:用来存储有序的、可以重复的数据(主要用来替换数组,"动态"数组)

????????????????实现类:ArrayList(主要实现类)、LinkedList、Vector

????????Set子接口:用来存储无序的、不可重复的数据(类似于高中讲的"集合")

????????????????实现类:HashSet(主要实现类)、LinkedHashSet、TreeSet

Map接口:用于存储具有映射关系“key-value对”的集合,即一对一对的数据,也称双列数据集合。(类似于高中的函数、映射。(x1,y1),(x2,y2) ---> y = f(x) )

????????HashMap(主要实现类)、LinkedHashMap、TreeMap、Hashtable、Properties

JDK提供的集合API位于java.util包内

图示:集合框架全图

简图1:Collection接口继承树

简图2:Map接口继承树

2、Collection接口及方法

Collection是所有单列集合的父接口,因此在Collection中定义了单列集合(List和Set)通用的一些方法,这些方法可用于操作所有的单列集合

JDK不提供此接口的任何直接实现,而是提供更具体的子接口(如:Set和List)去实现。

2.1 添加方法

public boolean add(E e)

????????添加元素对象到当前集合中。

public boolean addAll(Collection other)

????????添加other集合中的所有元素对象到当前集合中

package com.suyv.list;

import org.junit.Test;

import java.util.ArrayList;
import java.util.Collection;

/**
*@Author: 憨憨浩浩
*@CreateTime: 2023-12-15 13:55
*@Description: 添加方法
*/
public class ListDemo01 {

    // public boolean add(E e);
    // 添加元素对象到当前集合中。
    @Test
    public void Test(){
        //ArrayList是Collection的子接口List的实现类之一。
        Collection col1 = new ArrayList();
        col1.add("小李广");
        col1.add("扫地僧");
        col1.add("石破天");
        System.out.println(col1);
    }

    // public boolean addAll(Collection other);
    // 添加other集合中的所有元素对象到当前集合中。
    @Test
    public void Test02(){
        Collection col1 = new ArrayList();
        col1.add("小李广");
        col1.add("扫地僧");
        col1.add("石破天");

        Collection col2 = new ArrayList();
        col2.add("Tom");
        col2.add("Jerry");

        col1.addAll(col2);
        System.out.println(col1);   // [小李广, 扫地僧, 石破天, Tom, Jerry]
    }

    // add()和addAll()的区别
    @Test
    public void Test03(){
        Collection col1 = new ArrayList();
        col1.add("小李广");
        col1.add("扫地僧");
        col1.add("石破天");

        Collection col2 = new ArrayList();
        col2.add("Tom");
        col2.add("Jerry");

        col1.add(col2);
        System.out.println(col1);   // [小李广, 扫地僧, 石破天, [Tom, Jerry]]
        System.out.println(col1.size());    // 4
    }

    @Test
    public void Test04(){
        Collection col1 = new ArrayList();
        col1.add("小李广");
        col1.add("扫地僧");
        col1.add("石破天");

        Collection col2 = new ArrayList();
        col2.add("Tom");
        col2.add("Jerry");

        col1.addAll(col2);
        System.out.println(col1);   // [小李广, 扫地僧, 石破天, Tom, Jerry]
        System.out.println(col1.size());    // 5
    }

}

注意:add()和addAll()方法都可以添加一个集合,但是使用add()添加是把col1集合当做一个元素加入到col2集合中,而addAll()方法是把col1集合里面的每个元素分别加入到col2集合中。

2.2 删除方法

public void clear()

????????清空集合元素

public boolean remove(Object obj)

????????从当前集合中删除第一个找到的与obj对象equals返回true的元素。

public boolean removeAll(Collection coll)

????????从当前集合中删除所有与coll集合中相同的元素。

public boolean retainAll(Collection coll)

????????从当前集合中删除两个集合中不同的元素,使得当前集合仅保留与coll集合中的元素相同的元素,即当前集合中仅保留两个集合的交集

package com.suyv.list;

import org.junit.Test;

import java.util.ArrayList;
import java.util.Collection;

/**
*@Author: 憨憨浩浩
*@CreateTime: 2023-12-15 14:46
*@Description: 删除方法
*/
public class ListDemo02 {

    // public void clear()
    // 清空集合元素
    @Test
    public void Test01(){
        Collection col1 = new ArrayList();
        col1.add("小李广");
        col1.add("扫地僧");
        col1.add("石破天");
        col1.clear();
        System.out.println(col1);       // []
    }

    // public boolean remove(Object obj)
    // 从当前集合中删除第一个找到的与obj对象equals返回true的元素。
    @Test
    public void Test02(){
        Collection col1 = new ArrayList();
        col1.add("小李广");
        col1.add("扫地僧");
        col1.add("石破天");
        col1.add("小李广");
        col1.add("小李广");
        col1.remove("小李广");
        System.out.println(col1);   // [扫地僧, 石破天, 小李广, 小李广]
    }

    // public boolean removeAll(Collection coll)
    // 从当前集合中删除所有与coll集合中相同的元素。
    @Test
    public void Test03(){
        Collection col1 = new ArrayList();
        col1.add("小李广");
        col1.add("扫地僧");
        col1.add("石破天");
        col1.add("小李广");
        col1.add("小李广");

        Collection col2 = new ArrayList();
        col2.add("小李广");
        col2.add("石震天");

        col1.removeAll(col2);
        System.out.println(col1);       // [扫地僧, 石破天]
    }


    // public boolean retainAll(Collection coll)
    // 从当前集合中删除两个集合中不同的元素,使得当前集合仅保留与coll集合中的元素相同的元素,
    // 即当前集合中仅保留两个集合的交集
    @Test
    public void Test04(){
        Collection col1 = new ArrayList();
        col1.add("小李广");
        col1.add("扫地僧");
        col1.add("石破天");

        Collection col2 = new ArrayList();
        col2.add("小李广");
        col2.add("石震天");

        col1.retainAll(col2);
        System.out.println(col1);       // [小李广]
    }

}

2.3 判断方法

public int size()

????????获取当前集合中实际存储的元素个数

public boolean isEmpty()

????????判断当前集合是否为空集合

public boolean contains(Object obj)

????????判断当前集合中是否存在一个与obj对象equals返回true的元素

public boolean containsAll(Collection coll)

????????判断coll集合中的元素是否在当前集合中都存在。即coll集合是否是当前集合的“子集“

public boolean equals(Object obj)

????????判断当前集合与obj是否相等

package com.suyv.list;

import org.junit.Test;

import java.util.ArrayList;
import java.util.Collection;

/**
*@Author: 憨憨浩浩
*@CreateTime: 2023-12-15 14:55
*@Description: TODO
*/
public class ListDemo03 {

    // public boolean isEmpty()
    // 判断当前集合是否为空集合
    // public int size()
    // 获取当前集合中实际存储的元素个数
    @Test
    public void Test01(){
        Collection col1 = new ArrayList();
        System.out.println("coll在添加元素之前,isEmpty = " + col1.isEmpty());  // true
        col1.add("小李广");
        col1.add("扫地僧");
        col1.add("石破天");
        col1.add("佛地魔");
        System.out.println("coll的元素个数" + col1.size());      // 4

        System.out.println("coll在添加元素之后,isEmpty = " + col1.isEmpty());      // false
    }

    // public boolean contains(Object obj)
    // 判断当前集合中是否存在一个与obj对象equals返回true的元素
    @Test
    public void Test02() {
        Collection col1 = new ArrayList();
        col1.add("小李广");
        col1.add("扫地僧");
        col1.add("石破天");

        System.out.println(col1.contains("小李广"));   // true
        System.out.println(col1.contains("佛地魔"));   // false

    }

    // public boolean containsAll(Collection coll)
    // 判断coll集合中的元素是否在当前集合中都存在。即coll集合是否是当前集合的“子集“
    @Test
    public void Test03(){
        Collection col1 = new ArrayList();
        col1.add("小李广");
        col1.add("扫地僧");
        col1.add("石破天");

        Collection col2 = new ArrayList();
        col2.add("小李广");
        col2.add("扫地僧");

        Collection col3 = new ArrayList();
        col3.add("佛地魔");

        System.out.println(col1.containsAll(col2));     // true
        System.out.println(col1.containsAll(col3));     // false

    }

    // public boolean equals(Object obj)
    // 判断当前集合与obj是否相等
    @Test
    public void Test04(){
        Collection col1 = new ArrayList();
        col1.add("小李广");
        col1.add("扫地僧");
        col1.add("石破天");

        Collection col2 = new ArrayList();
        col2.add("小李广");
        col2.add("扫地僧");
        col2.add("石破天");

        System.out.println(col1.equals("小李广")); // false
        System.out.println(col1.equals(col2));  // true
    }

}

2.4 其他方法

public Object[] toArray()

????????返回包含当前集合中所有元素的数组

public hashCode()

????????获取集合对象的哈希值

iterator()

????????返回迭代器对象,用于集合遍历

package com.suyv.list;

import org.junit.Test;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Iterator;

/**
*@Author: 憨憨浩浩
*@CreateTime: 2023-12-15 15:40
*@Description: TODO
*/
public class ListDemo04 {

    // public Object[] toArray()
    // 返回包含当前集合中所有元素的数组
    @Test
    public void Test01(){
        Collection col1 = new ArrayList();
        col1.add("小李广");
        col1.add("扫地僧");
        col1.add("石破天");
        col1.add("佛地魔");

        // public Object[] toArray()
        //集合转换为数组:集合的toArray()方法
        Object[] objects = col1.toArray();
        System.out.println(Arrays.toString(objects));       // [小李广, 扫地僧, 石破天, 佛地魔]

        //对应的,数组转换为集合:调用Arrays的asList(Object ...objs)
        Object[] arr1 = new Object[]{123,"AA","CC"};
        Collection list = Arrays.asList(arr1);
        System.out.println(list);       // [123, AA, CC]
    }

    // public hashCode()
    // 获取集合对象的哈希值
    @Test
    public void Test02(){
        Collection col1 = new ArrayList();
        col1.add("小李广");
        col1.add("扫地僧");
        col1.add("石破天");
        col1.add("佛地魔");

        System.out.println(col1.hashCode());        // -1082961350
    }

    // iterator()
    // 返回迭代器对象,用于集合遍历
    @Test
    public void Test03(){
        Collection col1 = new ArrayList();
        col1.add("小李广");
        col1.add("扫地僧");
        col1.add("石破天");
        col1.add("佛地魔");

        // 获取迭代器对象
        Iterator iterator = col1.iterator();//获取迭代器对象

        // 遍历集合
        while (iterator.hasNext()){ // 判断迭代器中是否有元素可迭代
            System.out.print(iterator.next());      // 取出下一个元素
            System.out.print('\t');     // 小李广	扫地僧	石破天	佛地魔
        }
    }
}

3、Iterator迭代器

3.1 Iterator概述

在程序开发中,经常需要遍历集合中的所有元素。针对这种需求,JDK专门提供了一个接口java.util.Iterator。Iterator接口也是Java集合中的一员,但它与Collection、Map接口有所不同,Collection接口与Map接口主要用于存储元素,而Iterator主要用于迭代访问(即遍历)Collection中的元素,因此Iterator对象也被称为迭代器。

3.2 什么是迭代

迭代:即Collection集合元素的通用获取方式。在取元素之前先要判断集合中有没有元素,如果有,就把这个元素取出来,继续在判断,如果还有就再取出来。一直把集合中的所有元素全部取出。这种取出方式专业术语称为迭代。

3.3 Iterator接口

在程序开发中,经常需要遍历集合中的所有元素。针对这种需求,JDK专门提供了一个接口java.util.Iterator。Iterator接口也是Java集合中的一员,但它与Collection、Map接口有所不同。

  • Collection接口与Map接口主要用于存储元素
  • Iterator,被称为迭代器接口,本身并不提供存储对象的能力,主要用于遍历Collection中的元素

Collection接口继承了java.lang.Iterable接口,该接口有一个iterator()方法,那么所有实现了Collection接口的集合类都有一个iterator()方法,用以返回一个实现了Iterator接口的对象。

  • public Iterator iterator(): 获取集合对应的迭代器,用来遍历集合中的元素的。
  • 集合对象每次调用iterator()方法都得到一个全新的迭代器对象,默认游标都在集合的第一个元素之前。

Iterator接口的常用方法如下:

  • public E next():返回迭代的下一个元素。
  • public boolean hasNext():如果仍有元素可以迭代,则返回 true。

注意:在调用it.next()方法之前必须要调用it.hasNext()进行检测。若不调用,且下一条记录无效,直接调用it.next()会抛出NoSuchElementException异常。

package com.suyv.list;

import org.junit.Test;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;

/**
*@Author: 憨憨浩浩
*@CreateTime: 2023-12-15 16:55
*@Description: 迭代器的使用
*/
public class ListDemo05 {

    @Test
    public void Test01(){
        Collection col1 = new ArrayList();
        col1.add("小李广");
        col1.add("扫地僧");
        col1.add("石破天");

        Iterator iterator = col1.iterator();
        System.out.println(iterator.next());    // 小李广
        System.out.println(iterator.next());    // 扫地僧
        System.out.println(iterator.next());    // 石破天
        // System.out.println(iterator.next());    // NoSuchElementException
    }

    @Test
    public void Test02(){
        Collection col1 = new ArrayList();
        col1.add("小李广");
        col1.add("扫地僧");
        col1.add("石破天");

        // 获取迭代器对象
        Iterator iterator = col1.iterator();
        // 判断是否还有元素可迭代
        while (iterator.hasNext()){
            // 取出下一个元素
            System.out.println(iterator.next());
        }
    }
}

3.4 迭代器的实现原理

Iterator迭代器对象在遍历集合时,内部采用指针的方式来跟踪集合中的元素,接下来通过一个图例来演示Iterator对象迭代元素的过程:

使用Iterator迭代器删除元素:java.util.Iterator迭代器中有一个方法:void remove() ;

Iterator iter = coll.iterator();//回到起点
while(iter.hasNext()){
    Object obj = iter.next();
    if(obj.equals("Tom")){
        iter.remove();
    }
}

注意:

  • Iterator可以删除集合的元素,但是遍历过程中通过迭代器对象的remove方法,不是集合对象的remove方法。
  • 如果还未调用next()或在上一次调用 next() 方法之后已经调用了 remove() 方法,再调用remove()都会报IllegalStateException。
  • Collection已经有remove(xx)方法了,为什么Iterator迭代器还要提供删除方法呢?因为迭代器的remove()可以按指定的条件进行删除。

例如:要删除以下集合元素中的偶数

import org.junit.Test;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;

public class TestIteratorRemove {
    @Test
    public void Test01(){
        Collection coll = new ArrayList();
        coll.add(1);
        coll.add(2);
        coll.add(3);
        coll.add(4);
        coll.add(5);
        coll.add(6);

        Iterator iterator = coll.iterator();
        while(iterator.hasNext()){
            Integer element = (Integer) iterator.next();
            if(element % 2 == 0){
                iterator.remove();
            }
        }
        System.out.println(coll);
    }
}

在JDK8.0时,Collection接口有了removeIf 方法,即可以根据条件删除。

import org.junit.Test;

import java.util.ArrayList;
import java.util.Collection;
import java.util.function.Predicate;

public class TestCollectionRemoveIf {
    @Test
    public void test01(){
        Collection coll = new ArrayList();
        coll.add("小李广");
        coll.add("扫地僧");
        coll.add("石破天");
        coll.add("佛地魔");
        System.out.println("coll = " + coll);

        coll.removeIf(new Predicate() {
            @Override
            public boolean test(Object o) {
                String str = (String) o;
                return str.contains("地");
            }
        });
        System.out.println("删除包含\"地\"字的元素之后coll = " + coll);
    }
}

4、增强for

增强for循环(也称foreach循环)是JDK1.5以后出来的一个高级for循环,专门用来遍历数组和集合的。它的内部原理其实是个Iterator迭代器,所以在遍历的过程中,不能对集合中的元素进行增删操作。

增强for格式

for(元素的数据类型  变量 : Collection集合or数组的变量名){ 
    //写操作代码
}

它用于遍历Collection和数组。通常只进行遍历元素,不要在遍历的过程中对集合元素进行增删操作。

增强for遍历数组和集合

package com.suyv.list;

import org.junit.Test;

import java.util.ArrayList;
import java.util.Collection;

/**
*@Author: 憨憨浩浩
*@CreateTime: 2023-12-15 17:06
*@Description: 增强for循环遍历数组和集合
*/
public class ListDemo06 {

    // 遍历数组
    @Test
    public void Test01(){
        int[] arr = {1, 2, 3, 4, 5};
        for (int i: arr) {
            System.out.println(i);
        }

        String[] names = {"张三","李四","王五"};
        for (String name : names) {
            System.out.println(name);
        }

    }

    // 遍历结合
    @Test
    public void Test02(){
        Collection col1 = new ArrayList();
        col1.add("张三");
        col1.add("李四");
        col1.add(1);
        col1.add(3.14);

        for (Object obj: col1) {
            System.out.println(obj);
        }
    }
}

新for循环必须有被遍历的目标。目标只能是Collection或者是数组。新式for仅仅作为遍历操作出现。

5、List集合

注意:在JavaSE中List名称的类型有两个,一个是java.util.List集合接口,一个是java.awt.List图形界面的组件,别导错包了。

5.1 什么是List集合

java.util.List接口继承自Collection接口,是单列集合的一个重要分支,习惯性地会将实现了List接口的对象称为List集合。在List集合中允许出现重复的元素,所有的元素是以一种线性方式进行存储的,在程序中可以通过索引来访问集合中的指定元素。另外,List集合还有一个特点就是元素有序,即元素的存入顺序和取出顺序一致。

5.2 List集合的特点

它是一个元素存取有序的集合。例如,存元素的顺序是11、22、33。那么集合中,元素的存储就是按照11、22、33的顺序完成的)。

它是一个带有索引的集合,通过索引就可以精确的操作集合中的元素(与数组的索引是一个道理)。

集合中可以有重复的元素,通过元素的equals方法,来比较是否为重复的元素。

总结:List集合类中元素有序、且可重复,集合中的每个元素都有其对应的顺序索引。

5.3 List集合常用方法

List除了从Collection集合继承的方法外,List 集合里添加了一些根据索引来操作集合元素的方法

5.3.1 插入元素

public void add(int index, Object ele)

????????在index位置插入ele元素

public boolean addAll(int index, Collection eles)

????????从index位置开始将eles中的所有元素添加进来

package com.suyv.list;

import org.junit.Test;

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

/**
*@Author: 憨憨浩浩
*@CreateTime: 2023-12-15 17:18
*@Description: List的插入方法
*/
public class ListDemo07 {

    // public void add(int index, Object ele)
    // 在index位置插入ele元素
    @Test
    public void Test01(){
        // 创建List集合对象
        List list = new ArrayList<String>();

        // 往 尾部添加 指定元素
        list.add("图图");
        list.add("小美");
        list.add("不高兴");
        System.out.println(list);       // [图图, 小美, 不高兴]

        list.add(1,"没头脑");
        System.out.println(list);       // [图图, 没头脑, 小美, 不高兴]
    }

    @Test
    public void Test02(){
        // 创建List集合对象
        List list = new ArrayList();

        // 往 尾部添加 指定元素
        list.add("图图");
        list.add("小美");
        list.add("不高兴");
        System.out.println(list);       // [图图, 小美, 不高兴]

        List list1 = new ArrayList();
        list1.add("图图妈");
        list1.add("图图爸");

        list.addAll(1,list1);
        System.out.println(list);       // [图图, 图图妈, 图图爸, 小美, 不高兴]

    }
}

5.3.2 获取元素

public Object get(int index)

????????获取指定index位置的元素

public List subList(int fromIndex, int toIndex)

????????返回从fromIndex到toIndex位置的子集合

package com.suyv.list;

import org.junit.Test;

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

/**
*@Author: 憨憨浩浩
*@CreateTime: 2023-12-15 17:25
*@Description: List的获取元素方法
*/
public class ListDemo08 {

    // public Object get(int index)
    // 获取指定index位置的元素
    @Test
    public void Test01(){
        // 创建List集合对象
        List list = new ArrayList<String>();
        list.add("图图");
        list.add("小美");
        list.add("不高兴");
        System.out.println(list);       // [图图, 小美, 不高兴]

        System.out.println(list.get(1));    // 小美

    }

    // public List subList(int fromIndex, int toIndex)
    // 返回从fromIndex到toIndex位置的子集合
    @Test
    public void Test02(){
        // 创建List集合对象
        List list = new ArrayList<String>();
        list.add("图图");
        list.add("没头脑");
        list.add("小美");
        list.add("不高兴");
        System.out.println(list);       // [图图, 没头脑, 小美, 不高兴]

        System.out.println(list.subList(1,3));    // [没头脑, 小美]
    }
}

5.3.3 获取元素索引

public int indexOf(Object obj)

????????返回obj在集合中首次出现的位置

public int lastIndexOf(Object obj)

????????返回obj在当前集合中末次出现的位置

package com.suyv.list;

import org.junit.Test;

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

/**
*@Author: 憨憨浩浩
*@CreateTime: 2023-12-15 17:32
*@Description: List获取元素索引方法
*/
public class ListDemo09 {

    // public int indexOf(Object obj)
    // 返回obj在集合中首次出现的位置
    @Test
    public void Test01(){
        // 创建List集合对象
        List list = new ArrayList<String>();
        list.add("图图");
        list.add("没头脑");
        list.add("小美");
        list.add("不高兴");
        list.add("图图");
        list.add("没头脑");
        System.out.println(list);       // [图图, 没头脑, 小美, 不高兴, 图图, 没头脑]

        System.out.println(list.indexOf("图图"));     // 0
    }

    // public int lastIndexOf(Object obj)
    // 返回obj在当前集合中末次出现的位置
    @Test
    public void Test02(){
        // 创建List集合对象
        List list = new ArrayList<String>();
        list.add("图图");
        list.add("没头脑");
        list.add("小美");
        list.add("不高兴");
        list.add("图图");
        list.add("没头脑");
        System.out.println(list);       // [图图, 没头脑, 小美, 不高兴, 图图, 没头脑]

        System.out.println(list.lastIndexOf("图图"));     // 4
    }
}

5.3.4 替换和删除元素

public Object remove(int index)

????????移除指定index位置的元素,并返回此元素

public Object set(int index, Object ele)

????????设置指定index位置的元素为ele

package com.suyv.list;

import org.junit.Test;

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

/**
*@Author: 憨憨浩浩
*@CreateTime: 2023-12-15 17:37
*@Description: List替换和删除元素方法
*/
public class ListDemo10 {

    // public Object remove(int index)
    // 移除指定index位置的元素,并返回此元素
    @Test
    public void Test01(){
        // 创建List集合对象
        List list = new ArrayList<String>();
        list.add("图图");
        list.add("没头脑");
        list.add("小美");
        list.add("不高兴");
        list.add("图图");
        list.add("没头脑");
        System.out.println(list);       // [图图, 没头脑, 小美, 不高兴, 图图, 没头脑]

        System.out.println(list.remove(4));     // 图图
        System.out.println(list);   // [图图, 没头脑, 小美, 不高兴, 没头脑]
    }

    // public Object set(int index, Object ele)
    // 设置指定index位置的元素为ele
    @Test
    public void Test02(){
        // 创建List集合对象
        List list = new ArrayList<String>();
        list.add("图图");
        list.add("没头脑");
        list.add("小美");
        list.add("不高兴");
        list.add("图图");
        list.add("没头脑");
        System.out.println(list);       // [图图, 没头脑, 小美, 不高兴, 图图, 没头脑]

        System.out.println(list.set(4,"牛爷爷"));     // 图图
        System.out.println(list);   // [图图, 没头脑, 小美, 不高兴, 牛爷爷, 没头脑]
    }
}

6、List集合的子类

List的子类特点:

????????ArrayList:

????????????????底层数据结构是数组,查询快,增删慢

????????????????线程不安全,效率高

????????LinkedList:

????????????????底层数据结构是双向链表,查询慢,增删快

????????????????线程不安全,效率高

????????Vector:

????????????????底层数据结构是数组,查询快,增删慢

????????????????线程安全,效率低

6.1 List接口主要实现类:ArrayList

ArrayList 是 List 接口的主要实现类,本质上,ArrayList是对象引用的一个“动态”数组。

Arrays.asList(…) 方法返回的 List 集合,既不是 ArrayList 实例,也不是 Vector 实例。 Arrays.asList(…) 返回值是一个固定长度的 List 集合。

ArrayList集合中常用方法

方法名

说明

public void add(int index, E element)

将指定的元素,添加到该集合中的指定位置上。

public E get(int index)

返回集合中指定位置的元素·。

public E remove(int index)

移除列表中指定位置的元素, 返回的是被移除的元素。

public E set(int index, E element)

用指定元素替换集合中指定位置的元素,返回值的更新前的元素

public boolean add(E e)

将指定的元素添加到此列表的尾部

student实体类

package com.suyv.arrayList;
/**
*@Author: 憨憨浩浩
*@CreateTime: 2023-12-15 19:29
*@Description: Student实体类
*/
public class Student {
    private String id;
    private String name;

    public Student() {
    }

    public Student(String id, String name) {
        this.id = id;
        this.name = name;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

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

    @Override
    public String toString() {
        return "Student{" +
                "id='" + id + '\'' +
                ", name='" + name + '\'' +
                '}';
    }
}

ArrayList的使用

package com.suyv.arrayList;

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

/**
*@Author: 憨憨浩浩
*@CreateTime: 2023-12-15 19:28
*@Description: ArrayList的使用
*/
public class ArrayListDemo01 {
    public static void main(String[] args) {
        List<Student> list = new ArrayList<>();

        Student s1 = new Student();
        s1.setId("11");
        s1.setName("小包面");

        Student s2 = new Student();
        s2.setId("22");
        s2.setName("小肉丝");

        list.add(s1);
        list.add(s2);

        System.out.println(list);

        Iterator<Student> it = list.iterator();
        while (it.hasNext()){
            //注意返回的类型为是Student对象
            Student stu = it.next();
            System.out.println(stu.getId());
            System.out.println(stu.getName());
        }

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

        for (Student s : list){
            System.out.println(s.getName()+": "+s.getId());
        }

        System.out.println("=====================");
        for(int x = 0; x < list.size(); x++){
            Student stu = list.get(x);
            System.out.println(stu.getId()+": "+stu.getName());
        }
    }
}

6.2 List的实现类之二:LinkedList

对于频繁的插入或删除元素的操作,建议使用LinkedList类,效率较高。这是由底层采用链表(双向链表)结构存储数据决定的。

6.2.1 特有方法:

public void addFirst(Object obj)

????????将指定元素插入此列表的开头。

public void addLast(Object obj)

????????将指定元素添加到此列表的结尾。

public Object getFirst()

????????返回此列表的第一个元素。

public Object getLast()

????????返回此列表的最后一个元素。

public Object removeFirst()

????????移除并返回此列表的第一个元素。

public Object removeLast()

????????移除并返回此列表的最后一个元素。

public E pop()

????????从此列表所表示的堆栈处弹出一个元素。

public void push(E e)

????????将元素推入此列表所表示的堆栈。

public boolean isEmpty()

????????如果列表不包含元素,则返回true。

LinkedList是List的子类,List中的方法LinkedList都是可以使用,这里就不做详细介绍,我们只需要了解LinkedList的特有方法即可。在开发时,LinkedList集合也可以作为堆栈,队列的结构使用。

package com.suyv.arrayList;

import org.junit.Test;

import java.util.LinkedList;
import java.util.List;

/**
*@Author: 憨憨浩浩
*@CreateTime: 2023-12-15 19:41
*@Description: LinkedList的使用
*/
public class LinkedListDemo01 {
    // public void addFirst(Object obj)
    // 将指定元素插入此列表的开头。
    @Test
    public void Test01(){
        LinkedList list = new LinkedList();
        list.add("张三");
        list.add("李四");
        list.add("王五");
        System.out.println(list);       // [张三, 李四, 王五]

        list.addFirst("小明");
        System.out.println(list);       // [小明, 张三, 李四, 王五]
    }

    // public void addLast(Object obj)
    // 将指定元素添加到此列表的结尾。
    @Test
    public void Test02(){
        LinkedList list = new LinkedList();
        list.add("张三");
        list.add("李四");
        list.add("王五");
        System.out.println(list);       // [张三, 李四, 王五]

        list.addLast("小明");
        System.out.println(list);       // [张三, 李四, 王五, 小明]
    }

    // public Object getFirst()
    // 返回此列表的第一个元素。
    @Test
    public void Test03(){
        LinkedList list = new LinkedList();
        list.add("张三");
        list.add("李四");
        list.add("王五");
        System.out.println(list);       // [张三, 李四, 王五]

        System.out.println(list.getFirst());    // 张三
    }

    // public Object getLast()
    // 返回此列表的最后一个元素。
    @Test
    public void Test04(){
        LinkedList list = new LinkedList();
        list.add("张三");
        list.add("李四");
        list.add("王五");
        System.out.println(list);       // [张三, 李四, 王五]

        System.out.println(list.getLast());    // 王五
    }

    // public Object removeFirst()
    // 移除并返回此列表的第一个元素。
    @Test
    public void Test05(){
        LinkedList list = new LinkedList();
        list.add("张三");
        list.add("李四");
        list.add("王五");
        System.out.println(list);       // [张三, 李四, 王五]

        System.out.println(list.removeFirst());     // 张三
        System.out.println(list);       // [李四, 王五]
    }

    // public Object removeLast()
    // 移除并返回此列表的最后一个元素。
    @Test
    public void Test06(){
        LinkedList list = new LinkedList();
        list.add("张三");
        list.add("李四");
        list.add("王五");
        System.out.println(list);       // [张三, 李四, 王五]

        System.out.println(list.removeLast());     // 王五
        System.out.println(list);       // [张三, 李四]
    }

    // public E pop()
    // 从此列表所表示的堆栈处弹出一个元素。
    @Test
    public void Test07(){
        LinkedList list = new LinkedList();
        list.add("张三");
        list.add("李四");
        list.add("王五");
        System.out.println(list);       // [张三, 李四, 王五]

        list.pop();
        System.out.println(list);       // [李四, 王五]
    }

    // public void push(E e)
    // 将元素推入此列表所表示的堆栈。
    @Test
    public void Test08(){
        LinkedList list = new LinkedList();
        list.add("张三");
        list.add("李四");
        list.add("王五");
        System.out.println(list);       // [张三, 李四, 王五]

        list.push("小明");
        System.out.println(list);       // [小明, 张三, 李四, 王五]
    }

    // public boolean isEmpty()
    // 如果列表不包含元素,则返回true。
    @Test
    public void Test09(){
        LinkedList list = new LinkedList();
        System.out.println(list.isEmpty());     // true

        list.add("张三");
        list.add("李四");
        list.add("王五");

        System.out.println(list.isEmpty());       // false
    }
}

6.3 Vector集合

Vector 是一个古老的集合,JDK1.0就有了。大多数操作与ArrayList相同,区别之处在于Vector是线程安全的。

在各种List中,最好把ArrayList作为默认选择。当插入、删除频繁时,使用LinkedList;Vector总是比ArrayList慢,所以尽量避免使用。

6.3.1 特有方法:

public void addElement(Object obj)

????????添加元素

public void insertElementAt(Object obj,int index)

????????在指定位置添加元素

public void setElementAt(Object obj,int index)

????????修改指定位置元素

public void removeElement(Object obj)

????????移除元素

public void removeAllElements()

????????移除所有元素

public Object elementAt(int index)

????????获取指定位置对象

public Enumeration elements() Iterator iterator()

public boolean hasMoreElements() hasNext()

public Object nextElement() next()

package com.suyv.arrayList;

import org.junit.Test;

import java.util.Enumeration;
import java.util.Vector;

/**
*@Author: 憨憨浩浩
*@CreateTime: 2023-12-15 20:01
*@Description: Vector方法的使用
*/
public class VectorDemo01 {
    // public void addElement(Object obj)
    // 添加元素
    @Test
    public void Test01(){
        Vector vector = new Vector();
        vector.addElement("张三");
        vector.add("李四");
        vector.addElement("王五");
        System.out.println(vector);     // [张三, 李四, 王五]
    }

    // public void insertElementAt(Object obj,int index)
    // 在指定位置添加元素
    @Test
    public void Test02(){
        Vector vector = new Vector();
        vector.addElement("张三");
        vector.add("李四");
        vector.addElement("王五");

        vector.insertElementAt("小明",1);
        System.out.println(vector);     // [张三, 小明, 李四, 王五]
    }

    // public void setElementAt(Object obj,int index)
    // 修改指定位置元素
    @Test
    public void Test03(){
        Vector vector = new Vector();
        vector.addElement("张三");
        vector.add("李四");
        vector.addElement("王五");

        vector.setElementAt("小明",1);
        System.out.println(vector);     // [张三, 小明, 王五]
    }

    // public void removeElement(Object obj)
    // 移除元素
    @Test
    public void Test04(){
        Vector vector = new Vector();
        vector.addElement("张三");
        vector.add("李四");
        vector.addElement("王五");

        vector.removeElement("张三");
        System.out.println(vector);     // [李四, 王五]
    }

    // public void removeAllElements()
    // 移除所有元素
    @Test
    public void Test05(){
        Vector vector = new Vector();
        vector.addElement("张三");
        vector.add("李四");
        vector.addElement("王五");

        vector.removeAllElements();
        System.out.println(vector);     // []
    }

    // public Object elementAt(int index)
    // 获取指定位置对象
    @Test
    public void Test06(){
        Vector vector = new Vector();
        vector.addElement("张三");
        vector.add("李四");
        vector.addElement("王五");

        System.out.println(vector.elementAt(1));    // 李四
    }

    // public Enumeration elements()		Iterator iterator()
    // public boolean hasMoreElements()		hasNext()
    // public Object nextElement()		next()
    @Test
    public void Test07(){
        Vector vector = new Vector();
        vector.addElement("张三");
        vector.add("李四");
        vector.addElement("王五");

        Enumeration elements = vector.elements();
        while (elements.hasMoreElements()){
            System.out.println(elements.nextElement());
        }
    }
}

6.4 list集合的总结

List的子类特点:

????????ArrayList:

????????????????底层数据结构是数组,查询快,增删慢

????????????????线程不安全,效率高

????????LinkedList:

????????????????底层数据结构是链表,查询慢,增删快

????????????????线程不安全,效率高

????????Vector:

????????????????底层数据结构是数组,查询快,增删慢

????????????????线程安全,效率低

list集合特点:有序可重复

今后我们如何选择list的三个子类?

如果你想查询快:选ArrayListVector

如果你想增删快:选LinkedList

如果你想要效率高:选ArrayList,LinkedList

如果你想要效率低:选Vector

如果你想要线程安全:选Vector

如果你想要线程不安全:选ArrayList,LinkedList

以上都是分业务情况来决定你要用哪一个集合。如果你实在不知道该如何选择,你就选译:ArrayList

文章来源:https://blog.csdn.net/weixin_46612641/article/details/135033163
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。