大佬教程收集整理的这篇文章主要介绍了分分钟带你解决数据结构问题---- List接口中的ArrayList,大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
声明:博主gitee内附Java学习笔记
那么集合框架就是 Java 写好的一些数据结构c;像是顺序表c;链表c;栈和队列……这些数据结构不需要我们去手动的进行实现c;我们要做的就是去了解一下每个集合框架背后的数据结构c;那么我们今天就去了解一下List接口中的ArrayList
@H_489_16@
文章目录:
1、预备知识----泛型 2、预备知识----包装类 3、正式开始---- ArrayList与顺序表 4、模拟底层实现ArrayList 5、ArrayList实战模拟实现扑克牌
1、预备知识----泛型声明:在这里的泛型了解为主c;后面会有专门的博客去解释泛型c;这里只是简单的预备知识c;以看得懂原码为主要目的
以上的代码会引发一定的问题:
由于使用泛型 E/T 不可以实例化数组c;这里先提供一个可以使用c;但不完全正确的写法c;我们先看泛型使用的结果
由此我们开始探索泛型的意义:
@H_616_73@
正确书写代码需要使用到反射的知识c;后面有专门的博客进行讲解c;这里知道需要使用反射表示即可
@H_489_16@
2、预备知识----包装类Java引入的一种特殊的类c;即 8 种基本类型的包装类
@H_489_16@
注意:不是所有类都有包装类c;包装类主要针对的是 8 种基本数据类型
初识包装类
那么有基本数据类型c;为什么还需要有包装类?
使用包装类实现上述问题:
我们发现使用包装类去实现转换功能十分的简单c;省去编写一个方法去实现转换的操作
所以c;包装类的好处:
@H_489_16@
装包(装箱)与拆包(拆箱)
声明:利用 (Javap -c 文件名) 指令即可查看汇编代码
①、装包(装箱)
②、拆包(拆箱)
@H_@R_674_11235@_165@
所以装箱和拆箱在底层是会帮助我们去做一些东西
那么显示的拆箱和装箱又是怎么样的呢
①、显示的装箱
由于 Integer 是一个类(包装类)c;所以显示的装箱也可以这样写:
②、显示的拆箱
@H_489_16@
相关的一道阿里面试题:
相同的数值为什么会存在两个结果 ?常规来说两个数值一致应该都会返回 true
所以把 valueOf 这个方法作为问题的一个切入点c;Ctrl + 点击 valueOf 查看其原码
分析原码:
计算 cache 数组 范围:
所以数值在 [-128 ~ 127] 范围内就会直接返回数组中的该数值c;不在范围内会实例化一个新的对象
所以:
第一种情况 a 和 b 是相同的c;因为没有实例化新的对象c;从缓存数组中取出来直接赋值给 a 和 b
第二种情况 a 和 b 不相同的c;因为 129 超过范围实例化两个完全不同的对象c;所以在比较的时候 a 和 b 是不相同的
@H_489_16@
3、正式开始---- ArrayList与顺序表
ArrayList简介:
在集合框架中c;ArrayList是一个普通的类c;实现了List接口c;具体框架图如下:
@H_489_16@
ArrayList的使用:
①、实例化一个ArryaList
②、向 ArrayList 中添加数据(由于 ArrayList 重写了 toString 方法所以可以直接打印 list 即可)
循环遍历顺序表:
由于 ArrayList 实现了 Iterable 接口所以可以使用增强 for 循环进行打印
还可以使用迭代器进行打印
第二种针对于 List 的迭代器
@H_489_16@
有关 ListIterator 和 Iterator 的详解
声明:该内容参考博客
①、Iterator 接口
forEachRemaining(Consumer<? super E> action) 为每个剩余元素执行给定的操作,直到所有的元素都已经被处理或行动将抛出一个异常
hasNext(): 如果迭代器中还有元素c;则返回true。
next(): 返回迭代器中的下一个元素
remove(): 删除迭代器新返回的元素。
在使用 remove 方法的时候c;一定注意要先把元素全部迭代出来后c;再进行操作c;否则会引发异常
注意:
- Iterator只能单向移动。
- Iterator.remove()是唯一安全的方式来在迭代过程中修改集合;如果在迭代过程中以任何其它的方式修改了基本集合将会产生未知的行为。而且每调用一次next()方法c;remove()方法只能被调用一次c;如果违反这个规则将抛出一个异常。
②、ListIterator接口
ListIterator是一个功能更加强大的, 它继承于Iterator接口,只能用于各种List类型的访问。可以通过调用listIterator()方法产生一个指向List开始处的ListIterator, 还可以调用listIterator(n)方法创建一个一开始就指向列表索引为n的元素处的ListIterator。
ListIterator接口可以实现的功能:
- 双向移动(向前 / 向后遍历)
- 产生相对于迭代器在列表中指向的当前位置的前一个和后一个元素的索引.
- 可以使用set()方法替换它访问过的最后一个元素.
- 可以使用add()方法在Next()方法返回的元素之前或previous()方法返回的元素之后插入一个元素.
使用实例:(remove方法和上面介绍的使用方法一致)
两个接口之间的区别:
- ListIterator有add()方法c;可以向List中添加对象c;而Iterator不能
- ListIterator和Iterator都有hasNext()和next()方法c;可以实现顺序向后遍历c;但是ListIterator有hasPrevious()和previous()方法c;可以实现逆向(顺序向前)遍历。Iterator就不可以。
- ListIterator可以定位当前的索引位置c;nexTindex()和previousIndex()可以实现。Iterator没有此功能。
- 都可实现删除对象c;但是ListIterator可以实现对象的修改c;set()方法可以实现。Iierator仅能遍历c;不能修改
有关线程安全问题:
@H_489_16@
ArrayList 可实现的功能
①、插入元素
②、在某个位置插入元素
③、删除指定位置的元素
④、删除指定对象
⑤、获取指定下标位置的元素
⑥、更新指定下标位置的元素
⑦、清空顺序表
⑧、在顺序表中查找对应元素是否存在
⑨、查找元素在顺序表中的下标位置
⑩、按照给定下标范围分割顺序表
看一个问题:如果改变分割后的顺序表会影响到原来的顺序表吗
@H_489_16@
观察一个代码的有无问题
那大小为:0 的时候为什么也可以向顺序表中添加元素c;那我们看一下 add 方法的源代码解决此问题
@H_489_16@
4、模拟底层实现ArrayList搭建顺序表框架(参照源代码)
@H_489_16@
实现顺序表的操作(只实现前两个看得懂即可):
1、表尾添加数据
2、指定位置添加元素
@H_489_16@
5、ArrayList实战模拟实现扑克牌
1、搭建扑克牌框架(花色+大小)
2、提供合适的构造方法
3、花色和大小初始化的 Get Set 方法c;可以供其他使用
4、重写 toString 方法方便一会打印花色和大小
@H_489_16@
扑克牌的基本框架搭建好后c;进行玩牌三步走:
步骤一、买一副扑克牌(忽略大小王)
步骤二、买来的牌都是连着花色和大小的c;所以我们需要进行洗牌
步骤三、洗好的牌c;最后一步就是发到每个人的手中
@H_988_616@
@H_489_16@整体代码:
import java.util.ArrayList; import java.util.List; import java.util.Random; /** * Created with IntelliJ IDEA. * Description: * User: Lenovo * Date: 2022-01-05 * Time: 13:49 */ class Card{ private int sank; private String suit; public Card(int sank, String suit) { this.sank = sank; this.suit = suit; } public int getSank() { return sank; } public void setSank(int sank) { this.sank = sank; } public String getSuit() { return suit; } public void setSuit(String suit) { this.suit = suit; } @Override public String toString() { return "["+this.suit+" "+this.sank+"]"; } } public class Test3 { private static final String[] suits = {"ɦ5;","♣","♦","♠"}; private static List<Card> buyCard(){ ArrayList<Card> list = new ArrayList<>(); for (int i = 0; i < 4; i++) { for (int j = 1; j <= 13; j++) { list.add(new Card(j,suits[i])); } } return list; } private static void swap(List<Card> cards, int i, int j){ Card tmp = cards.get(i); cards.set(i, cards.get(j)); cards.set(j,tmp); } private static void shuffle(List<Card> cards){ int size = cards.size(); for (int i = size - 1; i > 0 ; i--) { Random rd = new Random(); int rand = rd.nexTint(i); swap(cards,i,rand); } } private static void sendCards(List<Card> cards){ ArrayList<List<Card>> hand = new ArrayList<>(); List<Card> hand1 = new ArrayList<>(); List<Card> hand2 = new ArrayList<>(); List<Card> 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++) { Card card = cards.remove(0); hand.get(j).add(card); } } System.out.println("第一个人牌:"+hand1); System.out.println("第二个人牌:"+hand2); System.out.println("第三个人牌:"+hand3); System.out.println("剩余的牌"+cards); } public static void @H_884_720@main(String[] args) { List<Card> cards = buyCard(); //买牌 System.out.println("买牌:"+cards); //洗牌 shuffle(cards); System.out.println("洗牌:"+cards); //发牌 sendCards(cards); } }
本章结束
有任何问题随时联系博主c;尽全力解决c;感谢支持!!!!!!
❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️
以上是大佬教程为你收集整理的分分钟带你解决数据结构问题---- List接口中的ArrayList全部内容,希望文章能够帮你解决分分钟带你解决数据结构问题---- List接口中的ArrayList所遇到的程序开发问题。
如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。