Java集合框架:ArrayList详解

news/2024/10/30 13:29:30/

目录

一、ArrayList简介

二、ArrayList源码介绍(动态扩容以及构造方法是如何实现的)

 1. 扩容机制:

  源码:

   源码详解: ​编辑

 如何扩容:

 2. 扩容源码详解:

 三、ArrayList的构造方法

四、ArrayList的几种遍历方式

五、ArrayList练习

   1. 实现洗牌算法

    2. 杨辉三角


     ​​​常见的线性表结构:顺序表,链表,栈,队列。(线性表在逻辑上是线性结构,也就是一条线,但是在物理结构上不一定是连续的,通常是以数组和链表的形式存储)

     顺序表:用一段物理地址连续的存储空间来存储数据元素,一般采用数组存储。

一、ArrayList简介

    在集合框架中,ArrayList是一个类,实现了List接口:

1. ArrayList是以泛型的方式实现的,使用时必须先实例化

2. ArrayList实现了randomAccess接口,所以ArrayList支持随机访问

3. ArrayList实现了Cloneable接口,ArrayList时可以克隆的
4. ArrayList不是线程安全的,(Vector是线程安全的)
5. ArrayList是一段连续的空间,可以动态扩容,是动态的顺序表

二、ArrayList源码介绍(动态扩容以及构造方法是如何实现的)

1. 扩容机制:

public static void main(String[] args) {ArrayList<Integer> arrayList = new ArrayList<>();arrayList.add(1);
}

  源码:

public ArrayList() {this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;}private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};

    如下代码;当我们new一个ArrayList数组的时候,我们可以看到ArrayList的源码,此时并没有开辟一块内存空间,而是new了一个空的数组,所以应该是在add第一个数据元素的时候开辟的空间,我们需要再看一下add() 方法的源码:

public boolean add(E e) {ensureCapacityInternal(size + 1);  // Increments modCount!!elementData[size++] = e;return true;}private void ensureCapacityInternal(int minCapacity) {ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));}private static int calculateCapacity(Object[] elementData, int minCapacity) {if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {return Math.max(DEFAULT_CAPACITY, minCapacity);}return minCapacity;}private void ensureExplicitCapacity(int minCapacity) {modCount++;// overflow-conscious codeif (minCapacity - elementData.length > 0)grow(minCapacity);}

   源码详解:

 如何扩容:

private void grow(int minCapacity) {// overflow-conscious codeint oldCapacity = elementData.length;int newCapacity = oldCapacity + (oldCapacity >> 1);if (newCapacity - minCapacity < 0)newCapacity = minCapacity;if (newCapacity - MAX_ARRAY_SIZE > 0)newCapacity = hugeCapacity(minCapacity);// minCapacity is usually close to size, so this is a win:elementData = Arrays.copyOf(elementData, newCapacity);}

  2. 扩容源码详解:

 三、ArrayList的构造方法

ArrayList( )无参数构造
ArrayList(Collection<? extends E> c)只要实现了Collection接口的类都可以作为这个构造方法的参数
ArrayList(int initialCapacity)指定顺序表初始容量

    构造方法的演示:

public static void main(String[] args) {//无参构造,在第一次add元素时给初始容量大小是10,扩容按1.5倍扩容ArrayList<Integer> arrayList = new ArrayList<>();arrayList.add(1);arrayList.add(2);//可以传参一个实现了Collection接口的类的实例化对象LinkedList<Integer> linkedList = new LinkedList<>();//可以传参一个具体的对象,之后这个ArrayList1数组就包含了这个LinkedList中的数据ArrayList<Integer> arrayList1 = new ArrayList<>(linkedList);//带一个参数的构造:这个参数多大,这个数组的初始化容量就是多大ArrayList<Integer> arrayList2 = new ArrayList<>(20);
}

四、ArrayList的几种遍历方式

1. 直接打印输出,因为在父类AbstractCollection中重写了toString()方法

2. for循环遍历数组中的元素

3. for each循环遍历数组中的元素
4. Iterator迭代器循环遍历数组中的元素
public static void main(String[] args) {//无参构造,在第一次add元素时给初始容量大小是10,扩容按1.5倍扩容List<Integer> arrayList = new ArrayList<>();arrayList.add(1);arrayList.add(2);arrayList.add(3);//直接遍历:在AbstractCollection中重写了toString方法System.out.println(arrayList);//for循环遍历for (int i = 0; i < arrayList.size(); i++) {System.out.print(arrayList.get(i) + " ");}//for each遍历System.out.println();for (Integer x : arrayList) {System.out.print(x + " ");}//迭代器的遍历Iterator<Integer> it = arrayList.listIterator();while (it.hasNext()) {System.out.println(it.next() + " ");}
}

五、ArrayList练习

   1. 实现洗牌算法

package PokerGame;public class Poker {//定义花色private String suit;//数字private int rank;public Poker(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;}@Overridepublic String toString() {return "{" + suit + " " + rank + "}";}
}
package PokerGame;import java.util.ArrayList;
import java.util.List;
import java.util.Random;public class Game {private static final String[] suits = {"♥", "♣", "♦", "♠"};public List<Poker> buyPoker() {List<Poker> pokers = new ArrayList<>();//每一张Poker都需要有四种颜色for (int i = 0; i < 4; i++) {//每一种颜色都需要生成13张牌for (int j = 1; j <= 13; j++) {Poker poker = new Poker(suits[i],j);pokers.add(poker);}}return pokers;}public void shuffle(List<Poker> pokers) {for (int i = pokers.size() - 1; i > 0; i--) {Random random = new Random();int index = random.nextInt(i);//这里就是生成一个0-51的随机数//交换: 生成一个随机数,从最后一张牌开始和前边的牌交换swap(pokers,i,index);}}private void swap(List<Poker> pokers,int i, int j) {Poker tmp = pokers.get(i);pokers.set(i,pokers.get(j));//这里调用的是List的set方法pokers.set(j,tmp);}public List<List<Poker>> game(List<Poker> pokers) {List<List<Poker>> hand = new ArrayList<>();List<Poker> hand1 = new ArrayList<>();List<Poker> hand2 = new ArrayList<>();List<Poker> hand3 = new ArrayList<>();hand.add(hand1);hand.add(hand2);hand.add(hand3);//最外层循环 控制轮数for (int i = 0; i < 5; i++) {for (int j = 0; j < 3; j++) {Poker removePoker = pokers.remove(0);hand.get(j).add(removePoker);}}return hand;}
}
package PokerGame;import java.util.List;public class Text {public static void main(String[] args) {Game game = new Game();List<Poker> pokers = game.buyPoker();System.out.println(pokers);//洗牌System.out.println("洗牌:");game.shuffle(pokers);//System.out.println(pokers);//揭牌:List<List<Poker>> hand = game.game(pokers);System.out.println("揭牌:");for (int i = 0; i < hand.size(); i++) {System.out.println("第"+(i+1)+"个人的牌:"+hand.get(i));}//剩下的牌System.out.println(pokers);}
}

    2. 杨辉三角

//杨辉三角public List<List<Integer>> generate(int numRows) {List<List<Integer>> ret = new ArrayList<>();List<Integer> row = new ArrayList<>();row.add(1);ret.add(row);for (int i = 1; i < numRows; i++) {//i就是行的下标List<Integer> prevRow = ret.get(i-1);List<Integer> curRow = new ArrayList<>();curRow.add(1);//第一个1//中间的数值for (int j = 1; j < i; j++) {//j就是列的下标int x = prevRow.get(j) + prevRow.get(j - 1);curRow.add(x);}curRow.add(1);ret.add(curRow);}return ret;}


http://www.ppmy.cn/news/332264.html

相关文章

超好用的八款办公软件,你的电脑都装了吗?

如何才能提高效率&#xff0c;早点把工作做完&#xff1f;这大概是每个打工人心中都有的问题。用好这几款办公软件&#xff0c;至少能帮你减少三分之一的办公步骤&#xff01; 01 免费UI设计软件 —— Pixso 说到画图&#xff0c;大部分人都会选择去下载“破解版”的AI、PS或…

办公用计算机的配置,办公电脑用什么配置的好,2018办公电脑配置推荐

我们明白在生活中离不天电脑&#xff0c;但是在办公室电脑堪称不缺乏一件工具&#xff0c;一般而言你只要自由选择一套标准配置的电脑就可以已完成你办公的市场需求。下面小编就来给大家讲解一下办公电脑用什么配备的好及2017办公电脑配置推荐。 办公电脑配置推荐1、1000元配备…

主板BIOS被破坏时的解决方法

电脑开机的时候不能自检&#xff0c;提示BIOS版本后&#xff0c;下面的提示是“ROM BIOS Checksum Error”&#xff0c;然后提示插入“System Disk”。 这种现象是某些主板对BIOS被破坏时采取的一项保护功能。以上提示其实是此主板BIOS中的BootBlock在起作用&#xff0…

计算机主板可以随意更换硬件吗,电脑主板可以随意换吗?满足这些条件才行

原标题&#xff1a;电脑主板可以随意换吗&#xff1f;满足这些条件才行 很多玩家都会有这样的疑问&#xff0c;那就是&#xff0c;电脑的主板可以随意更换吗&#xff1f;答案是&#xff0c;在一定的条件下是可以更换的&#xff01;接下来&#xff0c;笔者就为大家解释一下。 主…

换主板后mysql服务启动不了_电脑换主板有什么影响?

如果是换相同型号的主板&#xff0c;那么基本没什么影响&#xff0c;最多就是更新一下驱动&#xff1b;如果是更换成其他型号不一样的主板&#xff0c;那影响就比较大了&#xff0c;轻者会造成电脑的一些硬件驱动不良&#xff0c;重者可能频繁导致电脑蓝屏、死机&#xff0c;需…

检测计算机主板是否坏掉,解决办法:如何判断cpu是否坏以及主板是否坏,如何检测主板故障...

很多时候我都不知道发生了什么。我们的主板出手指与插槽簧片接触不良&#xff1b;也可能是记忆棒上的金手指。表面镀金效果不好。经过长时间的工作&#xff0c;镀金表面会出手指被氧化。 如果上述方法不能解决问题&#xff0c;则可以尝试新的内存模块&#xff1b;否则&#xff…

背光板坏了有必要修吗?

大家都知道背光板的组成部分包括&#xff1a;导光板、反射膜、扩散膜、包边纸、以及灯珠&#xff0c;这些零部件是缺一不可&#xff0c;在实际生产过程中&#xff0c;不可避免的也会造成损坏&#xff0c;那么假如背光坏了有必要修吗&#xff1f; 再回答这个问题之前&#xff0c…

详解电脑换主板需要重装系统吗

电脑使用久后难免会遇到一些故障问题&#xff0c;比如说电脑硬件损坏&#xff0c;电脑主板故障等。当出现电脑主板损坏需要更换的时候&#xff0c;有网友不知道电脑换主板需要重装系统吗&#xff1f;下面小编就跟大家聊聊电脑换主板是否需要重装系统。 首先如果是换了跟之前一…