分分钟带你解决数据结构问题---- List接口中的ArrayList
声明:博主gitee内附Java学习笔记
文章前言:
那么集合框架就是 Java 写好的一些数据结构,像是顺序表,链表,栈和队列……这些数据结构不需要我们去手动的进行实现,我们要做的就是去了解一下每个集合框架背后的数据结构,那么我们今天就去了解一下List接口中的ArrayList
文章目录:
1、预备知识----泛型
2、预备知识----包装类
3、正式开始---- ArrayList与顺序表
4、模拟底层实现ArrayList
5、ArrayList实战模拟实现扑克牌
1、预备知识----泛型
声明:在这里的泛型了解为主,后面会有专门的博客去解释泛型,这里只是简单的预备知识,以看得懂原码为主要目的
以上的代码会引发一定的问题:
由于使用泛型 E/T 不可以实例化数组,这里先提供一个可以使用,但不完全正确的写法,我们先看泛型使用的结果
由此我们开始探索泛型的意义:
正确书写代码需要使用到反射的知识,后面有专门的博客进行讲解,这里知道需要使用反射表示即可
2、预备知识----包装类
Java引入的一种特殊的类,即 8 种基本类型的包装类
注意:不是所有类都有包装类,包装类主要针对的是 8 种基本数据类型
初识包装类
那么有基本数据类型,为什么还需要有包装类?
使用包装类实现上述问题:
我们发现使用包装类去实现转换功能十分的简单,省去编写一个方法去实现转换的操作
所以,包装类的好处:
装包(装箱)与拆包(拆箱)
声明:利用 (Javap -c 文件名) 指令即可查看汇编代码
①、装包(装箱)
②、拆包(拆箱)
所以装箱和拆箱在底层是会帮助我们去做一些东西
那么显示的拆箱和装箱又是怎么样的呢
①、显示的装箱
由于 Integer 是一个类(包装类),所以显示的装箱也可以这样写:
②、显示的拆箱
相关的一道阿里面试题:
相同的数值为什么会存在两个结果 ?常规来说两个数值一致应该都会返回 true
所以把 valueOf 这个方法作为问题的一个切入点,Ctrl + 点击 valueOf 查看其原码
分析原码:
计算 cache 数组 范围:
所以数值在 [-128 ~ 127] 范围内就会直接返回数组中的该数值,不在范围内会实例化一个新的对象
所以:
第一种情况 a 和 b 是相同的,因为没有实例化新的对象,从缓存数组中取出来直接赋值给 a 和 b
第二种情况 a 和 b 不相同的,因为 129 超过范围实例化两个完全不同的对象,所以在比较的时候 a 和 b 是不相同的
3、正式开始---- ArrayList与顺序表
ArrayList简介:
在集合框架中,ArrayList是一个普通的类,实现了List接口,具体框架图如下:
ArrayList的使用:
①、实例化一个ArryaList
②、向 ArrayList 中添加数据(由于 ArrayList 重写了 toString 方法所以可以直接打印 list 即可)
循环遍历顺序表:
由于 ArrayList 实现了 Iterable 接口所以可以使用增强 for 循环进行打印
还可以使用迭代器进行打印
第二种针对于 List 的迭代器
有关 ListIterator 和 Iterator 的详解
声明:该内容参考博客
①、Iterator 接口
forEachRemaining(Consumer<? super E> action) 为每个剩余元素执行给定的操作,直到所有的元素都已经被处理或行动将抛出一个异常
hasNext(): 如果迭代器中还有元素,则返回true。
next(): 返回迭代器中的下一个元素
remove(): 删除迭代器新返回的元素。
在使用 remove 方法的时候,一定注意要先把元素全部迭代出来后,再进行操作,否则会引发异常
注意:
- Iterator只能单向移动。
- Iterator.remove()是唯一安全的方式来在迭代过程中修改集合;如果在迭代过程中以任何其它的方式修改了基本集合将会产生未知的行为。而且每调用一次next()方法,remove()方法只能被调用一次,如果违反这个规则将抛出一个异常。
②、ListIterator接口
ListIterator是一个功能更加强大的, 它继承于Iterator接口,只能用于各种List类型的访问。可以通过调用listIterator()方法产生一个指向List开始处的ListIterator, 还可以调用listIterator(n)方法创建一个一开始就指向列表索引为n的元素处的ListIterator。
ListIterator接口可以实现的功能:
- 双向移动(向前 / 向后遍历)
- 产生相对于迭代器在列表中指向的当前位置的前一个和后一个元素的索引.
- 可以使用set()方法替换它访问过的最后一个元素.
- 可以使用add()方法在next()方法返回的元素之前或previous()方法返回的元素之后插入一个元素.
使用实例:(remove方法和上面介绍的使用方法一致)
两个接口之间的区别:
- ListIterator有add()方法,可以向List中添加对象,而Iterator不能
- ListIterator和Iterator都有hasNext()和next()方法,可以实现顺序向后遍历,但是ListIterator有hasPrevious()和previous()方法,可以实现逆向(顺序向前)遍历。Iterator就不可以。
- ListIterator可以定位当前的索引位置,nextIndex()和previousIndex()可以实现。Iterator没有此功能。
- 都可实现删除对象,但是ListIterator可以实现对象的修改,set()方法可以实现。Iierator仅能遍历,不能修改
有关线程安全问题:
ArrayList 可实现的功能
①、插入元素
②、在某个位置插入元素
③、删除指定位置的元素
④、删除指定对象
⑤、获取指定下标位置的元素
⑥、更新指定下标位置的元素
⑦、清空顺序表
⑧、在顺序表中查找对应元素是否存在
⑨、查找元素在顺序表中的下标位置
⑩、按照给定下标范围分割顺序表
看一个问题:如果改变分割后的顺序表会影响到原来的顺序表吗
观察一个代码的有无问题
那大小为:0 的时候为什么也可以向顺序表中添加元素,那我们看一下 add 方法的源代码解决此问题
4、模拟底层实现ArrayList
搭建顺序表框架(参照源代码)
实现顺序表的操作(只实现前两个看得懂即可):
1、表尾添加数据
2、指定位置添加元素
5、ArrayList实战模拟实现扑克牌
1、搭建扑克牌框架(花色+大小)
2、提供合适的构造方法
3、花色和大小初始化的 Get Set 方法,可以供其他使用
4、重写 toString 方法方便一会打印花色和大小
扑克牌的基本框架搭建好后,进行玩牌三步走:
步骤一、买一副扑克牌(忽略大小王)
步骤二、买来的牌都是连着花色和大小的,所以我们需要进行洗牌
步骤三、洗好的牌,最后一步就是发到每个人的手中
整体代码:
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;}@Overridepublic String toString() {return "["+this.suit+" "+this.sank+"]";}
}
public class Test3 {private static final String[] suits = {"♥","♣","♦","♠"};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 main(String[] args) {List<Card> cards = buyCard();//买牌System.out.println("买牌:"+cards);//洗牌shuffle(cards);System.out.println("洗牌:"+cards);//发牌sendCards(cards);}
}
本章结束
有任何问题随时联系博主,尽全力解决,感谢支持!!!!!!
❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️
分分钟带你解决数据结构问题---- List接口中的ArrayList相关推荐
- java cxf 入口统一_分分钟带你玩转 Web Services【2】CXF
在实践中一直在使用 JAX-WS 构建 WebService 服务,服务还是非常稳定.高效的. 但还是比较好奇其他的 WebService 开源框架,比如:CXF/Axis2/Spring WS等. ...
- Python版本的数据结构书_《用Python解决数据结构与算法问题》
源于经典 数据结构作为计算机从业人员的必备基础,Java, c 之类的语言有很多这方面的书籍,Python 相对较少, 其中比较著名的一本 problem-solving-with-algorithm ...
- 输入文字时自动带空格解决办法
输入文字时自动带空格解决办法: 把输入法中的全角改为半角,即: 把 改为
- 分分钟带你搞定Android开发圆形头像
转载请注明来源: http://blog.csdn.net/kjunchen/article/details/50573326 分分钟带你搞定Android开发圆形头像 目前在应用开发中,矩形的头像基 ...
- 分分钟带你杀入Kaggle Top 1%
不知道你有没有这样的感受,在刚刚入门机器学习的时候,我们一般都是从MNIST.CIFAR-10这一类知名公开数据集开始快速上手,复现别人的结果,但总觉得过于简单,给人的感觉太不真实.因为这些数据太&q ...
- @retention注解作用_分分钟带你玩转SpringBoot自定义注解
在工作中,我们有时候需要将一些公共的功能封装,比如操作日志的存储,防重复提交等等.这些功能有些接口会用到,为了便于其他接口和方法的使用,做成自定义注解,侵入性更低一点.别人用的话直接注解就好.下面就来 ...
- 全家桶靠边站 用Windows自带功能解决3大难题
虽然咱们每天都在用装着Windows的电脑,但依旧会忽略掉Windows系统自带的很多功能.啥,觉得自己是老司机? 所以说,各位童鞋咱们得谦虚点.比如今天小编就为大家带来了3个Windows自带的隐藏 ...
- Carson带你学数据结构:手把手带你了解 ”图“ 所有知识!(含DFS、BFS)
前言 本文主要讲解 数据结构中的图 结构,包括 深度优先搜索(DFS).广度优先搜索(BFS).最小生成树算法等,希望你们会喜欢. 目录 1. 简介 数据结构的中属于 圆形结构 的逻辑结构 具体介绍如 ...
- Python带你了解数据结构【二】
上次我们介绍了线性的数据结构,数组,链表,栈,队列,这次我们来看看非线性的数据结构. 非线性的数据结构主要是:树(Tree),图(Graph),堆(Heap),散列表(Hash) 树(Tree) 谈到 ...
最新文章
- 为什么要参加java培训?有哪些优势?
- iOS自定义View 控件自动计算size能力
- 计算机视觉界CV牛人牛事
- 数据结构于算法—线性表
- Java常用API(六)Date 日期类介绍及使用
- Middleware Monitor Cockpit SMWP
- P3389-[模板]高斯消元法
- 如何在idea中使用Mybatis-generator插件快速生成代码
- 《大数据》第1期“研究”——大数据是数据、技术,还是应用
- 傅立叶变换,时域,频域二
- struts2学习 - action - 1
- 总结——达内视频(三)
- steam显示不能连接网络连接服务器,steam请检查网络连接
- 一元、二元函数图像绘制
- Java网络 1.3 开发工具介绍
- 原生js制作动画效果
- 院士李德毅:大数据认知(演讲全文)
- Excel数据可视化——使用图标集显示数据的意义
- MyEclipse中maven的下载、配置及安装
- 通过git的方式使用SVN(附原SVN命令)
热门文章
- 面向对象的特征二 继承性
- SAP 财务 KP26 计划作业价格维护
- ZOJ Monthly, August 2012 题解
- 马哥Linux运维2013
- 通过服务器能查到对方的信息吗,来看!通过微博用户名能查到对方什么信息?...
- System.Data.OracleClient 需要 Oracle 客户端软件 version 8.1.7 或更高版本
- 带宽计算方式,视频通讯上行下行服务器需求
- 【SQL】MySQL的查询语句
- upgrade pip
- 寻找热门查询,300万个查询字符串中统计最热门的10个查询