首页 > 其他分享 >ArrayList和顺序表(下)

ArrayList和顺序表(下)

时间:2024-10-14 15:53:04浏览次数:3  
标签:顺序 ArrayList list System add println out

1. Java本身提供的ArrayList

        在ArrayList和顺序表(上)那一节里面,我们自己实现了ArrayList的底层大部分代码,在这个基础上,我们就可以开始来了解Java本身提供的ArrayList.

        1.1 ArrayList的三种构造方法

        

方法解释
ArrayList()无参构造
ArrayList(Collection<? extends E > c)利用其他的Collection构造ArrayList
ArratList(int innitialCapacity)指定顺序表初始容量

        我们先来介绍第一和第三个        

        第一个构造方法,如果我们不设置任何参数,这里会直接给我们一个空的Object数组,里面没有大小.

        第二个构造方法,我们指定的容量是合法的,我们就产生一个指定容量大小的数组,

        第三个构造方法,我们必须要理解  Collection<? extends E > c 这个是什么意思

我们来举个例子

所以我们就晓得第二个构造方法的主要用法了:

1. 该集合类必须实现Collection接口

2. 在第一个<>设置的类型必须是第二个<>的子类或者它自己

这样就能实现直接把另一个实例的内容作为我新的实例的内容.

          我们来看代码:

public static void main(String[] args) {
        //ArrayList第二个构造方法 ,要求必须实现Collection,并且放进去的东西是子类(这个搞清楚是谁的子类)
        ArrayList<Integer> list = new ArrayList<>();//TODO 虽然没有分配内存
        list.add(1);//TODO 结论1.但是第一次Add的时候会分配大小为10的内存
        list.add(2);//TODO 结论2.如果超过了,就会1.5倍自动扩容
        list.add(3);//添加元素
        list.add(0,99);
        for (int i = 0; i < list.size(); i++) {
            System.out.print(list.get(i)+" ");
        }
        System.out.println();
        //相当于直接把一组数据放进来了
        ArrayList<Number> list2 = new ArrayList<>(list);//Integer是Number的子类,因此可以放进来
        LinkedList<Integer> list1 = new LinkedList<>();
        list1.add(1);
        list1.add(2);
        list1.add(4);
        ArrayList<Number> list3 = new ArrayList<>(list1);//Integer是Number的子类,因此可以放进来
        list3.add(1123);
        list3.add(1124);
        System.out.println(list3);
        System.out.println(list1);
}

        我们主要要主要这个        

        我们可以来看看源码(了解即可)

        结论:

1. 我们在创建ArrayList实例的时候,不设置参数,我们调用的是无参构造方法,里面是一个空的数组,没有分配内存.

2. 当第一次add的时候,我们才会分配大小为10的内存

3. 如果add方法检测出size大小等于数组大小,就会进行1.5倍的扩容

        1.2 ArrayList方法的介绍

       

方法解释
boolean add(E e)在最后一个有效数据后面插入e
void add(int index,E e)把插入到index位置
void addAll(Collection<? extends E> c)在尾巴插入c中的元素
E remove(int index)删除index位置上的元素
boolean remove(Object o)删除遇到的第一个o
E get(int index)获取index下标位置的元素
E set(int index,E e)把下标index位置元素设置为e
E clear() 清空
boolean contains(Object o)判断o是否在线性表里面
int indexOf(Object o)返回第一个o所在的下标
int lastIndexOf(Object o)返回最后一个o的下标
List<E> subList(int fromIndex,int toIndex)截取部分list

我们来使用一下这些方法

   

public static void main(String[] args) {
    ArrayList<Integer> list = new ArrayList<>();
    ArrayList<Number> list1 = new ArrayList<>();
    list.add(1);//TODO add的使用
    list.add(2);
    list.add(3);
    list.add(10);
    list.add(9);
    list.add(90);
    list.add(90);
    list.add(2,54);
    list1.addAll(list);
    //我们是可以直接通过list打印,因为它实现的一个接口重写了toString方法
    System.out.println("list:"+list);
    System.out.println("list1:"+list1);
    System.out.println("=============");
    list.remove(1);//TODO remove的使用
    list.remove(new Integer(3));
    System.out.println("list:"+list);
    System.out.println("==========");
    System.out.println(list.get(2));//TODO get的使用
    list.set(3,190);//TODO get的使用
    System.out.println("list:"+list);
    System.out.println("==========");
    System.out.println(list.contains(1));//TODO contains的使用
    System.out.println(list.indexOf(90));//TODO indexOf的使用
    System.out.println(list.lastIndexOf(90));//TODO lastIndexOf的使用
    System.out.println(list);
    list.clear();
    System.out.println(list);
}
list:[1, 2, 54, 3, 10, 9, 90, 90]
list1:[1, 2, 54, 3, 10, 9, 90, 90]
=============
list:[1, 54, 10, 9, 90, 90]
==========
10
list:[1, 54, 10, 190, 90, 90]
==========
true
4
5
[1, 54, 10, 190, 90, 90]
[]

我们需要注意的几个地方

addAll()里面我们放的是一个Number类型或者其子类的对象

remove里面,如果我们是想移除一个数,而不是移除下标的数,我们里面的参数就是引用类型的对象

list.remove(new Integer(3));

还有一个方法

List<E> subList(int fromIndex,int toIndex)

public static void main(String[] args) {
    ArrayList<Integer> list = new ArrayList<>();
    list.add(1);
    list.add(2);
    list.add(3);
    list.add(4);
    List<Integer> list1 = list.subList(0,2);
    System.out.println("list1" + list1);
    System.out.println("list" + list);
    System.out.println("====");
    list1.add(123);
    list1.set(0,99);
    System.out.println("list1" + list1);
    System.out.println("list" + list);
}
list1[1, 2]
list[1, 2, 3, 4]
====
list1[99, 2, 123]
list[99, 2, 123, 3, 4]

        我们可以得到一下几个结论:

        1. subList的参数设置是[第一个参数,第二个参数)

        2. subList的返回值是一个List类型的

        3. 我们subList方法并不会产生一个新的对象,而是直接把list的地址传给了list2,因此我们操作list2的时候list也会发生改变 

         1.3 ArrayList的遍历

        ArrayList可以通过四种方式来进行遍历,直接打印对象名字,for循环,foreach,使用迭代器

        1> 我们直接通过打印对象名

                

        2> 我们通过for循环来打印

        3> 我们通过foreach来打印       

        4> 我们通过迭代器进行打印

         使用迭代器来遍历集合类,我们只需要实现Iterable接口即可

由下图可知,ArrayList是实现了Iterable接口的

        

因为迭代器写法我们比较陌生,我们再来看看它的形式

Iterator<引用数据类型> 对象名 = 实现了Iteratable接口的对象.Iterator();

whie(对象名.hasNext()) {
                System.out.print(it.next()+" ");

}      

2. 练习题

        2.1 杨辉三角

        题目:

        我们在写这个题目之前先了解一下List的二维数组的写法

解题步骤

1. 我们先处理第一行的数据,第一行就是1,我们直接把一维数组的第一行数据设置为1,然后把第一行放到二维数组里面

2. 从第2行开始我们开始计算每个list中的数据

        我们先准备当前行的数据,就需要一个List类型的一维数组,然后我们放入每一行的第一个元素,就是1,然后我们构造每一行中间的数据,我们需要获得上一行的数据,我们通过ret.get(i-1)获得上一行,然后构造下一行的中间数据,通过preRow.get(j-1),preRow.get(j)来获得上一行元素的前一个,和上一行的正上方一个,然后把他们相加就是本行数据的值,然后我们把它加入到当前行里面去.

3. 把1加入到当前行的最后一个位置

4. 把当前行加入到ret二维数组里面去

        整体代码

class YangHuiTriangle {
    public List<List<Integer>> generate(int numRows) {
        List<List<Integer>> ret = new ArrayList<>();
        List<Integer> list = new ArrayList<>();
        //TODO 1.先处理第一行的数据
        list.add(1);//每一行代表一个list,第一行放的元素是1
        ret.add(list);//把第一行放入二维数组
        //TODO 2.从第2行开始计算每个list中的数据
        for (int i = 1 ; i < numRows ;i++) {
            //TODO 3.先准备当前行数据
            List<Integer> curRow = new ArrayList<>();
            //TODO 4.当前行的第一个数据
            curRow.add(1);
            //TODO 5.准备当前行的中间元素:上一行的前一个,上一行的正上方一个
            //找到前一行
            List<Integer> preRow = ret.get(i - 1);
            //构造下一行
            for (int j = 1 ; j < i ; j++) {
                //通过get方法来获取顺序表里面的值
                int val = preRow.get(j)+preRow.get(j-1);
                //然后放进当前行里面
                curRow.add(val);
            }
            //TODO 6.准备当前行的最后一个数据
            curRow.add(1);
            //TODO 7.当前行放进ret二维数组里面
            ret.add(curRow);
        }
        return ret;
    }
}

        2.2 简单的洗牌算法

        主要的步骤

        1. 生成一副扑克牌

        2. 洗牌

        3. 发牌

我们规定3个人来抓牌,每个人轮流抓5张(一共抓了15张牌

        我们先构造出Card这个类,一个牌时由花色和数字组成的,我们在这个类里面设置这俩个属性,

并且提供相应的构造方法.又因为是private 修饰的,我们需要为这俩个属性设置set和get方法,并且我们重写了toString方法.

public class Card {
    private String suit;//花色
    private int rank;//数字

    public Card(String suit, int rank) {
        this.suit = suit;
        this.rank = rank;
    }

    public String getSuit() {
        return suit;
    }

    public void setSuit(String suit) {
        this.suit = suit;
    }

    public int getRank() {
        return rank;
    }

    public void setRank(int rank) {
        this.rank = rank;
    }
    //打印牌,需要toString方法

    @Override
    public String toString() {
        return suit+": " + rank+" ";
    }
}

 然后我们写一个cardDemo类来对Card进行构造



import java.awt.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

public class  CardDemo {
    //四种花色
    private final String[] suits = {"♥","♠","♦","♣"};
    
    //买牌
    public List<Card> buyCard() {
        List<Card> cardList = new ArrayList<>();
        //TODO 1.生成牌
        for (int i = 0; i < 4; i++) {//花色
            for (int j = 1; j <= 13; j++) {//数字
                Card card = new Card(suits[i],j);//每一张花色产生13个数字
                cardList.add(card);//把创建出来的每一张牌都放进去
            }
        }
        return cardList;
    }
    //TODO 2.洗牌
    public List<Card> shuffle(List<Card> cardList) {
        Random random = new Random();
        //我们从最后面开始,第50张和前面49张进行随机交,然后第49张和前面48张进行交换
        for (int i = cardList.size() - 1; i > 0 ; i--) {
            int index = random.nextInt(i);
            // 我们把 index 和 i 进行交换
            swap(cardList,i,index);
        }
        return cardList;
    }
    private void swap(List<Card> cardList,int a,int b) {
        Card stm = cardList.get(a);
        cardList.set(a,cardList.get(b));
        cardList.set(b,stm);
    }
    //TODO 3.发牌,三个人,每人轮流揭牌5张
    public void getCard(List<Card> cardList) {
        //每个人相当于一个一维的Card数组
        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);
        //3个人轮流抓五张
        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("第一个人的牌: ");
            System.out.println(hand1);
            System.out.println("第二个人的牌: ");
            System.out.println(hand2);
            System.out.println("第三个人的牌: ");
            System.out.println(hand3);
            System.out.println("剩下的牌: ");
            System.out.println(cardList);
        }

    }
}

我们分段进行解析这个代码:

1. 生成牌

        我们需要四种花色              

        每个花色有13张牌因此俩层循环嵌套,然后用Card来创建每一张牌,并且把每一张card放进cardList里面去

2. 洗牌

        我们从最后面开始,假设是第50张牌,我们就让它和前面49张牌随机一张进行交换

3. 发牌

        我们每一个人相当于一个Card数组,因此List<Card> hand1 = new ArratList<>();然后我们再生成一个二维数组hands,然后3个人轮流抓五张牌,每次抓一张牌就要把cardList的牌数减少一张(0),表示我们从最上面开始抓

标签:顺序,ArrayList,list,System,add,println,out
From: https://blog.csdn.net/2201_75880772/article/details/142914521

相关文章

  • element 穿梭框el-transfer 实现上下移动选中的数据顺序
    代码实现<template><div><el-buttontype="primary"size="default"@click="upDown('up')">up</el-button><el-buttontype="primary"size="default"@click="upDo......
  • JavaScript中的流程控制(顺序结构、分支结构、循环结构)
    流程控制1.概念在一个程序执行的过程中,各条代码的执行顺序对程序的结果是有直接影响的,很多时候要通过控制代码的执行顺序来实现我们完成的功能简单的理解:流程控制就是控制代码,按照一定的结构顺序来执行流程控制的分类:顺序结构分支结构循环结构2.顺序流程控......
  • MongoDB集群的启动和关闭顺序
    分片(Shard)环境中的启动和关闭1.启动这个具体的参照分片的配置,启动的顺序是configserver->副本集/分片(shardX)->->mongos2.关闭因为mongos是分片架构最前端的入口,所以关闭顺序:mongos->副本集/分片(shardX)->configserver单实例:直接关闭db.getSiblingDB(“admin”).shutdow......
  • 假如你从0到1开始学习网络安全,按照这个顺序就对了!
    从零开始学习网络安全是一个系统化的过程,它涉及到多个层面的技术和理论知识。网络安全的学习顺序可以按照由浅入深、逐步递进的原则进行,以下是一个建议的网络安全学习路径:1.基础知识阶段:-计算机网络基础:理解网络架构、TCP/IP协议栈、OSI七层模型、数据链路层到应用层的......
  • 1.入门与顺序结构
    第一题:学习了输出语句,请参照例题,编写一个程序,输出以下信息:**************************HelloWorld!**************************注意:Hello与World之间有一个空格以及大小写问题*也是输出的一部分,别光打印HelloWorld!输入格式:无需输入输出格式:*************************......
  • 一文通Java 锁:锁机制及锁常见问题的深入解析(Java 并发编程(偏向、轻/重量级、读写、可
    在并发编程中,锁机制是保障线程安全的核心工具。锁的类型、使用场景、以及锁引发的种种问题都是开发者在设计高并发系统时必须应对的挑战。本篇博客将围绕锁的类型、应用场景、以及常见的锁问题展开详细讨论,帮助大家深入理解Java锁机制的优缺点与其适用场景。文章目录......
  • 转AI产品,请按照这个顺序学习!一篇就够!
    之前有很多朋友知道我已经转行成功了想知道我到底如何学习现在我已经上班一段时间了根据我之前的学习计划又进行了复盘和修改这次更新的版本适合所有想要学习AI产品的朋友可以让你按照科学的方式学习~基本上用5周的时间即可,先入行再深入研究,时间不要拉的太长!第1周-了......
  • 顺序表功能的实现--插删
    我们先来定义一个基本的顺序表#defineintSLDataTypetypdefstructSeqlist{SLDataType*arr;intsize;intcapacity;}SL;这是我们接下来将要实现的功能//头部插⼊删除//尾部插⼊删除voidSLPushBack(SL*ps,SLDataTypex);//尾插voidSLPopBack(SL*p......
  • 自学网络安全(黑客技术)顺序太重要三个月成长计划
    ......
  • 网络安全(黑客技术)自学顺序太重要—90天成长计划
    ......