Java集合框架之如何使用List ArrayList LinkedList

技术Java集合框架之如何使用List ArrayList LinkedList这篇文章主要讲解了“Java集合框架之如何使用List ArrayList LinkedList”,文中的讲解内容简单清晰,易于学习与理解,

本文主要讲解“如何在Java Collection Framework中使用List ArrayList LinkedList”,简单明了,易学易懂。请跟随边肖的思路学习《如何在Java集合框架中使用列表数组列表链接列表》。

目录

1.目录

1.1常见的列表方法。

1.2代码示例。

2.数组列表

2.1导言

2.2数组列表的构造方法。

2.3 ArrayList底层数组的大小。

3.链接列表

3.1导言

3.2链表的构造方法。

4.练习题

5.扑克游戏。

1. List

1.1 List 的常见方法

方法描述布尔add(E e)后缀evoid add(int index,E element)将E插入索引位置布尔addAll(Collection?扩展E c)后缀c中的元素E remove(int index)删除索引位置的元素布尔remove(Object o)删除在获取索引位置的元素E集合(int index)时遇到的第一个oE get(int index)。e)将索引位置元素设置为elementvoid clear()和empty boolean contains(Object o),判断o是否在线性表中。返回第一个对象的索引.返回最后一个O的下标ListList (int from index,int toindex)截取列表

1.2 代码示例

的一部分。注:以下示例均取自单个代码,上下部分之间存在逻辑关系。

示例1:使用List构造一个带有形状元素的序列表。

listinterlist=new ArrayList();例如:后缀e。

list . add(1);

list . add(2);

System.out.println(列表);

//结果是:[1,2]例3:在索引位置插入e。

list.add(0,10);

System.out.println(列表);

//

结果为:[10, 1, 2]

示例四: 尾插 c 中的元素

List<Integer> list1=new LinkedList<>();
list1.add(99);
list1.add(100);
list.addAll(list1);
System.out.println(list);
// 结果为:[10, 1, 2, 99, 100]

只要是继承于 Collection 的集合类的元素都可以被插入进去,但要注意传过来的具体的类型要么是和 list 的具体类型是一样的,要么是 list 具体类型的子类

示例五: 删除 index 位置的元素

System.out.println(list.remove(0));
System.out.println(list);
// 结果为:10 和 [1, 2, 99, 100]

示例六: 删除遇到的第一个 o

System.out.println(list.remove((Integer) 100));
System.out.println(list);
// 结果为:true 和 [1, 2, 99]

示例七: 获取下标 index 位置的元素

System.out.println(list.get(0));
// 结果为:1

示例八: 将下标 index 位置元素设置为 element

System.out.println(list.set(2,3));
System.out.println(list);
// 结果为:99 和 [1, 2, 3]

示例九: 判断 o 是否在线性表中

System.out.println(list.contains(1));
// 结果为:true

示例十: 返回第一个 o 所在下标

System.out.println(list.indexOf(1));
// 结果为:0

示例十一: 返回最后一个 o 的下标

list.add(1);
System.out.println(list.lastIndexOf(1));
// 结果为:3

示例十二: 截取部分 list

List<Integer> list2=list.subList(1,3);
System.out.println(list2);
// 结果为:[2, 3]

注意,当我们将 list2 通过 set 更改元素,其实对 list 也会有影响

list2.set(0,5);
System.out.println(list2);
System.out.println(list);
// 结果为:[5, 3] 和 [1, 5, 3, 1]

通过 subList 方法进行的截取,得到的集合的数值指向的地址和原集合中数值的地址是一样的

2. ArrayList

2.1 介绍

ArrayList 类是一个可以动态修改的数组,与普通数组的区别就是它是没有固定大小的限制,我们可以添加或删除元素。其继承了 AbstractList,并实现了 List 接口。LinkedList 不仅实现了 List 接口,还实现了 Queue 和 Deque 接口,可以作为队列去使用。

ArrayList 类位于 java.util 包中,使用前需要引入它。

2.2 ArrayList 的构造方法

方法 描述
ArrayList() 无参构造
ArrayList(Collection<? extends E> c) 利用其他 Collection 构建 ArrayList
ArrayList(int initialCapacity) 指定顺序表初始容量

示例一:

ArrayList<Integer> list1 = new ArrayList<>();

示例二:

ArrayList<Integer> list2 = new ArrayList<>(10);
// 该构造方法就是在构建时就将底层数组大小设置为了10

示例三:

List<Integer> list = new ArrayList<>();
list.add(1);
list.add(2);
ArrayList<Integer> list3 = new ArrayList<>(list);

Collection<? extends E> c 只要是具体类型都和 list3 是一样的集合都可以放入转化成 ArrayList

2.3 ArrayList 底层数组的大小

当我们使用 add 方法给 ArrayList 的对象进行尾插时,突然想到了一个问题:既然 ArrayList 的底层是一个数组,那么这个数组有多大呢?

为了解决这个问题,我进行了如下探索

跳转到 ArrayList 的定义,我们看到了 elementDataDEFAULTCAPACITY_EMPTY_ELEMENTDATA

Java集合框架之如何使用List ArrayList LinkedList

跳转到 elementData 的定义,我们可以了解 ArrayList 底层是数组的原因

Java集合框架之如何使用List ArrayList LinkedList

跳转到 DEFAULTCAPACITY_EMPTY_ELEMENTDATA 的定义,初步分析得到这个数组其实是空的

Java集合框架之如何使用List ArrayList LinkedList

为什么这个数组是空的但存储元素的时候没有报异常呢?我们再去了解下 add 是怎样存储的

通过转到 ArrayList 的 add 方法的定义

Java集合框架之如何使用List ArrayList LinkedList

通过定义,不难发现,数组容量和 ensureCapacityInternal 这个东西有关,那我们就看看它的定义

Java集合框架之如何使用List ArrayList LinkedList

我们看里面的 calculateCapacity ,他有两个参数,此时数组为空,那么 minCapacity 就为 1。我们再转到 calculateCapacity 看看它的定义

Java集合框架之如何使用List ArrayList LinkedList

此时我们就好像可以与之前串起来了,当数组为 DEFAULTCAPACITY_EMPTY_ELEMENTDATA 时,就返回 DeFauLt_CAPACITYminCapacity(此时为1) 的最大值。DeFauLt_CAPACITY 其实是默认容量的意思,我们可以转到它的定义看看有多大

Java集合框架之如何使用List ArrayList LinkedList

DeFauLt_CAPACITY 的值是10,故 calculateCapacity 函数此时的返回值为10,最后我们再确定一下 ensureExplicitCapacity 是干啥的

Java集合框架之如何使用List ArrayList LinkedList

此时 minCapacity 的值是10,而数组为空时数组长度为0,所以进入 if 语句,执行 grow 方法,我们继续转到 grow 的定义

Java集合框架之如何使用List ArrayList LinkedList

此时我们就可以了解,当我们创建一个 ArrayList 时,其底层数组大小其实是0。当我们第一次 add 的时候,经过 grow ,数组的大小就被扩容为了10。并且这大小为10的容量放满以后,就会按1.5倍的大小继续扩容。至于这个数组最大能存放多少,大家可以再转到 MAX_ARRAY_SIZE 的定义去查看。

3. LinkedList

3.1 介绍

LinkedList 类是一种常见的基础数据结构,是一种线性表,但是并不会按线性的顺序存储数据,而是在每一个节点里存到下一个节点的地址。

Java 的 LinkedList 底层是一个双向链表,位于 java.util 包中,使用前需要引入它

3.2 LinkedList 的构造方法

方法 描述
LinkedList() 无参构造
LinkedList(Collection<? extends E> c) 利用其他 Collection 构建 LinkedList

示例一:

LinkedList<Integer> list1 = new LinkedList<>();

示例二:

List<Integer> list = new LinkedList<>();
list.add(1);
list.add(2);
LinkedList<Integer> list2 = new LinkedList<>(list);

Collection<? extends E> c 只要是具体类型都和 list2 是一样的集合都可以放入转化成 LinkedList

4. 练习题

习题一

题目描述:

霍格沃茨学院有若干学生(学生对象放在一个 List 中),每个学生有一个姓名(String)、班级(String)和考试成绩(double)。某次考试结束后,每个学生都获得了一个考试成绩。遍历 list 集合,并把每个学生对象的属性都打印出来

本题代码:

class Student{
    private String name;
    private String classes;
    private double score;
	// 重写构造方法
    public Student(String name, String classes, double score) {
        this.name = name;
        this.classes = classes;
        this.score = score;
    }
	// 构造 get 和 set 方法
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getClasses() {
        return classes;
    }
    public void setClasses(String classes) {
        this.classes = classes;
    }
    public double getScore() {
        return score;
    }
    public void setScore(double score) {
        this.score = score;
    }
	// 重写 toString 方法
    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", classes='" + classes + '\'' +
                ", score=" + score +
                '}';
    }
}
public class TestDemo {
    public static void main(String[] args) {
        ArrayList<Student> students = new ArrayList<>();
        students.add(new Student("哈利波特","大二班",95.5));
        students.add(new Student("赫敏格兰杰","小三班",93));
        students.add(new Student("罗恩韦斯莱","小二班",91));
        for(Student s: students){
            System.out.println(s);
        }   
    }
}
// 结果为:
// Student{name='哈利波特', classes='大二班', score=95.5}
// Student{name='赫敏格兰杰', classes='小三班', score=93.0}
// Student{name='罗恩韦斯莱', classes='小二班', score=91.0}

习题二

题目描述:

有一个 List 当中存放的是整形的数据,要求使用 Collections.sort 对 List 进行排序

该题代码:

public class TestDemo {
    public static void main(String[] args) {
        ArrayList<Integer> list = new ArrayList<>();
        list.add(3);
        list.add(7);
        list.add(1);
        list.add(6);
        list.add(2);
        Collections.sort(list);
        System.out.println(list);
    }
}
// 结果为:[1, 2, 3, 6, 7]

补充:

Collections 是一个工具类,sort 是其中的静态方法,它是用来对 List 类型进行排序的

注意:

如果具体的类是类似于习题一那样的 Student 类,该类中含有多个属性,那就不能直接使用这个方法。要对 comparator 或者 comparable 接口进行重写,确定比较的是哪个属性才行

习题三

题目描述:

输出删除了第一个字符串当中出现的第二个字符串中的字符的字符串,例如

String str1 = "welcome to harrypotter";
String str2 = "come";
// 结果为:wl t harrypttr

希望本题可以使用集合来解决

该题代码:

public static void removeS(String str1, String str2){
    if(str1==null || str2==null){
        return;
    }
    List<Character> list = new ArrayList<>();
    int lenStr1=str1.length();
    for(int i=0; i<lenStr1; i++){
        char c = str1.charAt(i);
        if(!str2.contains(c+"")){
            list.add(c);
        }
    }
    for(char ch: list){
        System.out.print(ch);
    }
}

5. 扑克牌小游戏

我们可以通过上述所学,运用 List 的知识,去写一个关于扑克牌的逻辑代码(如:获取一副牌、洗牌、发牌等等)

class Card{
    private String suit;   // 花色
    private int rank;       // 牌面值
    public Card(String suit, int rank){
        this.suit=suit;
        this.rank=rank;
    }
    @Override
    public String toString() {
        return "[ "+suit+" "+rank+" ] ";
    }
}
public class TestDemo {
    public static String[] suits = {"♣", "♦", "♥", "♠"};
    // 获取一副牌
    public static List<Card> getNewCards(){
        // 存放 52 张牌
        List<Card> card = new ArrayList<>();
        for(int i=0; i<4; i++){
            for(int j=1; j<=13; j++) {
                card.add(new Card(suits[i], j));
            }
        }
        return card;
    }
    public static void swap(List<Card> card, int i, int j){
        Card tmp = card.get(i);
        card.set(i, card.get(j));
        card.set(j, tmp);
    }
    // 洗牌
    public static void shuffle(List<Card> card){
        int size = card.size();
        for(int i=size-1; i>0; i--){
            Random random = new Random();
            int randNum = random.nextInt(i);
            swap(card, i, randNum);
        }
    }
    public static void main(String[] args) {
        // 得到一副新的牌
        List<Card> cardList = getNewCards();
        System.out.println("已获取新的扑克牌");
        System.out.println("洗牌:");
        shuffle(cardList);
        System.out.println(cardList);
        System.out.println("抓牌:(3个人,每人轮流抓牌总共抓5张)");
        List<Card> hand1 = new ArrayList<>();
        List<Card> hand2 = new ArrayList<>();
        List<Card> hand3 = new ArrayList<>();
        List<List<Card>> hands = new ArrayList<>();
        hands.add(hand1);
        hands.add(hand2);
        hands.add(hand3);
        for(int i=0; i<5; i++){
            for(int j=0; j<3; j++){
                Card card = cardList.remove(0);
                hands.get(j).add(card);
            }
        }
        System.out.println("第一个人的牌:"+hand1);
        System.out.println("第二个人的牌:"+hand2);
        System.out.println("第三个人的牌:"+hand3);
    }
}
/** 
结果为:
已获取新的扑克牌
洗牌:
[[ ♥ 9 ] , [ ♦ 6 ] , [ ♣ 8 ] , [ ♦ 2 ] , [ ♣ 6 ] , [ ♦ 4 ] , [ ♣ 11 ] , [ ♣ 9 ] , [ ♠ 8 ] , [ ♣ 5 ] , [ ♦ 8 ] , [ ♦ 10 ] , [ ♦ 1 ] , [ ♦ 12 ] , [ ♥ 10 ] , [ ♥ 7 ] , [ ♠ 12 ] , [ ♥ 12 ] , [ ♦ 7 ] , [ ♣ 13 ] , [ ♠ 6 ] , [ ♠ 5 ] , [ ♥ 3 ] , [ ♦ 5 ] , [ ♦ 11 ] , [ ♣ 12 ] , [ ♠ 7 ] , [ ♦ 3 ] , [ ♥ 5 ] , [ ♦ 13 ] , [ ♣ 1 ] , [ ♥ 8 ] , [ ♠ 10 ] , [ ♠ 4 ] , [ ♣ 4 ] , [ ♣ 7 ] , [ ♥ 1 ] , [ ♠ 1 ] , [ ♣ 3 ] , [ ♥ 11 ] , [ ♥ 13 ] , [ ♦ 9 ] , [ ♠ 13 ] , [ ♣ 10 ] , [ ♥ 6 ] , [ ♠ 11 ] , [ ♠ 3 ] , [ ♣ 2 ] , [ ♠ 2 ] , [ ♥ 2 ] , [ ♥ 4 ] , [ ♠ 9 ] ]
抓牌:(3个人,每人轮流抓牌总共抓5张)
第一个人的牌:[[ ♥ 9 ] , [ ♦ 2 ] , [ ♣ 11 ] , [ ♣ 5 ] , [ ♦ 1 ] ]
第二个人的牌:[[ ♦ 6 ] , [ ♣ 6 ] , [ ♣ 9 ] , [ ♦ 8 ] , [ ♦ 12 ] ]
第三个人的牌:[[ ♣ 8 ] , [ ♦ 4 ] , [ ♠ 8 ] , [ ♦ 10 ] , [ ♥ 10 ] ]
*/

上述代码中有一处代码是这样写的 List<List<Card>>,其实不难理解,这个类型其实就是 List 中存放的每个元素都是一个 List 类型的,并且每一个 List 元素中的元素都是 Card 类型,类似于二维数组。

感谢各位的阅读,以上就是“Java集合框架之如何使用List ArrayList LinkedList”的内容了,经过本文的学习后,相信大家对Java集合框架之如何使用List ArrayList LinkedList这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是,小编将为大家推送更多相关知识点的文章,欢迎关注!

内容来源网络,如有侵权,联系删除,本文地址:https://www.230890.com/zhan/47500.html

(0)

相关推荐

  • linux加载环境变量和文件头

    技术linux加载环境变量和文件头 linux加载环境变量和文件头Linux 目录结构及详细操作
    目录结构常见的目录结构Windows下:D: \ProgramFilesLinux下:/etc/sysc

    礼包 2021年12月14日
  • Spring使用tx标签配置的拦截器

    技术Spring使用tx标签配置的拦截器 Spring使用tx标签配置的拦截器xml version="1.0" encoding="UTF-8" beans xmlns ="http://www.s

    礼包 2021年10月19日
  • 如何更改Exchange2013的邮件发送频率限制

    技术如何更改Exchange2013的邮件发送频率限制这篇文章主要介绍如何更改Exchange2013的邮件发送频率限制,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!我们通过脚本或者程序去发送邮件

    攻略 2021年11月17日
  • 不惑之年是多少岁,人到不惑之年,有何感悟

    技术不惑之年是多少岁,人到不惑之年,有何感悟四十岁不是青春消逝不惑之年是多少岁,而是成熟人生的开始。人到了四十岁,己历练成熟,不会象年青时那样迷茫与困惑了。四十岁的人生阶段,事业己稳固,财富也有了积累,社会经验更加丰富,

    生活 2021年11月1日
  • 映射ADO.NET如何设置参数

    技术映射ADO.NET如何设置参数这篇文章主要为大家展示了“映射ADO.NET如何设置参数”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“映射ADO.NET如何设置参数”这篇文

    攻略 2021年12月1日
  • 怎么用Java实现判断括号的合法性

    技术怎么用Java实现判断括号的合法性本篇内容介绍了“怎么用Java实现判断括号的合法性”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,

    攻略 2021年11月15日