文章目录
😀1.基本数据类型和包装类直接的对应关系
基本就是类型的首字母大写,除了 Integer 和 Character。
注意这里 String 不是 包装类,是引用类型。(包装类针对基本数据类型)
包装类的装箱拆箱
ArrayList
注意这里埋了坑哦
😉ArrayList 的 几种打印方式
List 迭代器打印,外加 Listlterator的 add方法与remove方法注意事项
🤩ArrayList的常见方法
1.add方法
2.remove
3.get方法
4.set方法
5.clear 清空顺序表
6.contains 查找顺序表中的元素
public class Test {
public static void main(String[] args) {
ArrayList<String>list = new ArrayList<>();
list.add("a");
list.add("b");
list.add("c");
System.out.println(list);
System.out.println(list.contains("a"));
System.out.println(list.contains("f"));
}
}
7.indexOf 查找顺序表元素并返回下标
public class Test {
public static void main(String[] args) {
ArrayList<String>list = new ArrayList<>();
list.add("a");
list.add("b");
list.add("c");
System.out.println(list);
System.out.println(list.indexOf("a"));
System.out.println(list.indexOf("f"));
}
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6TJLpoXY-1654954789532)(C:\Users\A\AppData\Roaming\Typora\typora-user-images\image-20220608221123195.png)]
8.lastIndexOf 从后往前找 元素并返回下标
public class Test {
public static void main(String[] args) {
ArrayList<String>list = new ArrayList<>();
list.add("a");
list.add("b");
list.add("c");
list.add("c");
System.out.println(list);
System.out.println(list.lastIndexOf("c"));
System.out.println(list.indexOf("f"));
}
}
9.subList 截取字符串
😏填坑
🥰模拟实现ArrayList
1、add方法 添加元素
// 这里 实现 我们自己 的 ArrayList 可以参考 源码实现
class nameError extends RuntimeException {
public nameError(String message) {
super(message);
}
}
class ArrayErrow extends RuntimeException {
public ArrayErrow(String message) {
super(message);
}
}
class doesnotexistError extends RuntimeException {
public doesnotexistError(String message) {
super(message);
}
}
class MyArrayList<E> {
private Object[] elementData; // 数组,
private int usedSize;// 有效元素的数据个数
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
public MyArrayList() {
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}
public MyArrayList(int capacity) throws nameError {
if(capacity > 0) {
// 对参数进行判断
this.elementData = new Object[capacity];
}else if(capacity == 0) {
this.elementData = new Object[0];
}else {
throw new nameError("初始化的容量不能为负数");
}
}
/**
* 添加元素
* @param e
* @return
*/
public boolean add(E e) {
// 确定一个真正的容量,预测 --》扩容[将检查顺序表空和满和扩容放到了一起]
ensureCapacityInternal(usedSize+1);
elementData[usedSize] = e;
usedSize++;
return true;
}
private void ensureCapacityInternal(int minCapacity) {
//1.计算出需要的容量
int capacity = calculateCapacity(elementData,minCapacity);
//2.拿出计算出的容量 去看 满了扩容,空的 扩容
ensureExplicitCapacity(capacity);
}
// 判断是否满了
private void ensureExplicitCapacity(int minCapacity) {
// 进不去 if 语句 说明还没有放满
if(minCapacity - elementData.length > 0 ) {
// 现在 minCapacity 实际元素 如果大于 数组长度(容量) 就需要扩容
grow(minCapacity);
}
}
//private static final int DEFAULT_CAPACITY = 10;
private int calculateCapacity(Object[] elementData,int minCapacity) {
// 判断 是否 有分配 过 容量大小
if(elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
return Math.max(10,minCapacity);
}
return minCapacity;
// 这里返回 minCapacity 说明 分配过容量大小
// 分配过返回+1的值
}
private static int hugeCapacity (int minCapacity) {
if(minCapacity < 0) {
throw new ArrayErrow("给定的顺序表容量太大溢出错误");
}
return (minCapacity > Max_Array_size) ?
Integer.MAX_VALUE :
Max_Array_size;
}
private static final int Max_Array_size = Integer.MAX_VALUE - 8;
private void grow(int minCapacity) {
int oldCapacity = elementData.length;
int newCapacity = oldCapacity+(oldCapacity>>1);
if(newCapacity - minCapacity < 0) {
newCapacity = minCapacity;
}
if(newCapacity - Max_Array_size >0) {
newCapacity = hugeCapacity(minCapacity);
}
elementData = Arrays.copyOf(elementData, newCapacity);
}
private void copy(int index ,E e) {
for(int i = usedSize-1;i>=index;i--) {
elementData[i + 1] = elementData[i];
}
elementData[index] = e;
}
// 给 index 位置添加元素
public void add(int index,E e) {
rangeCheckForAdd(index);
// 判断是否 需要扩容
ensureCapacityInternal(usedSize+1);
copy(index,e);
usedSize++;
}
private void rangeCheckForAdd(int index){
if(index < 0 || index > size()) {
throw new IndexOutOfBoundsException("index位置不合法,无法插入");
}
}
public int size() {
return this.usedSize;
}
}
2.remove方法 删除 元素
// 删除 index 位置的 元素
public E remove(int index) {
rangeCheck(index);
E oldvalue = (E) elementData[index];
// 这里elementData为 Object类型要强转才能赋值
sub(index);
return oldvalue;
}
// 遍历寻找 数组中e 的元素是否存在
private int a(E e) {
for(int i = 0;i<usedSize;i++) {
if(elementData[i].equals(e)) {
return i;
}
}
return -1;
}
public void remove(E e) throws doesnotexistError {
int ret = a(e);
if(ret == -1) {
throw new doesnotexistError("要删除的元素不存在");
}else {
sub(ret);
}
}
3.get方法 查找 index 位置的信息
public void rangeCheck2(int index) throws nameError {
if(index < 0 || index > size()) {
throw new nameError("要获取信息的位置不合法");
}
}
public E get(int index) {
rangeCheck2(index);
return (E)this.elementData[index];
}
4.set方法 替换 index 位置的元素
public E set(int index , E e) {
rangeCheck2(index);
// 判断 index 位置的合法性
E oldvalue = (E) elementData[index];
elementData[index] = e;
return oldvalue;
}
5.clear方法清空 顺序表
一个一个置空 ,最后数组元素赋值为 0 就行
public void clear() {
for(int i = 0;i<usedSize;i++) {
elementData[i] = null;
}
usedSize = 0;
}
🤗完整
class nameError extends RuntimeException {
public nameError(String message) {
super(message);
}
}
class AarrayError extends RuntimeException {
public AarrayError(String message) {
super(message);
}
}
class doesnotexistError extends RuntimeException {
public doesnotexistError(String message) {
super(message);
}
}
public class MyArrayList<E>{
private Object[] elementData;
private int usedSize;
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
public MyArrayList() {
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
// 用来记录 elementData 是否 分配了空间
}
public MyArrayList(int capacity) throws nameError{
if(capacity > 0) {
this.elementData = new Object[capacity];
}else if(capacity == 0) {
this.elementData = new Object[0];
}else {
throw new nameError("初始化的容量不能为负数");
}
}
public boolean add(E e) {
ensureCapacityInternal(usedSize + 1); // Increments modCount!!
elementData[usedSize++] = e;
return true;
}
private void ensureCapacityInternal(int minCapacity ) {
// 判断是否分配了空间,真实的所需的空间
int capacity = calculateCapacity(elementData,minCapacity);
ensureExplicitCapacity(capacity);// 判断是否 需要扩容
}
private void ensureExplicitCapacity(int minCapacity) {
if(minCapacity - elementData.length >0) {
grow(minCapacity);
// 扩容
}
}
private int calculateCapacity(Object[] elementData,int minCapacity) {
// 先判断 是否分配了空间
if(elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
return Math.max(10,minCapacity);
}
// 如果分配了空间,就直接返回分配的空间
return minCapacity;
}
// 创建一个 第一边界
private static final int Max_Array_size = Integer.MAX_VALUE - 8;
private void grow(int minCapacity) {
int oldCapacity = elementData.length;
int newCapacity = oldCapacity+(oldCapacity>>1);
if(newCapacity - minCapacity <0) {
newCapacity = minCapacity;
}
if(minCapacity - Max_Array_size > 0) {
newCapacity = hugeCapacity(minCapacity);
}
this.elementData = Arrays.copyOf(elementData,newCapacity);
}
private int hugeCapacity(int mindCapacity) {
if(mindCapacity < 0 ) {
throw new AarrayError("开创的容量位置太大超出int 的最大容量");
}
return (mindCapacity > Max_Array_size) ? Integer.MAX_VALUE : Max_Array_size;
}
private void copy(int index,E e) {
for(int i = usedSize-1;i >=index;i--) {
elementData[i+1] = elementData[i];
}
elementData[index] = e;
usedSize++;
}
public void add(int index,E e) {
// 判断位置 是否合法
rangeCheckForAdd(index);
// 判断是否需要扩容
ensureCapacityInternal(usedSize+1);
copy(index,e);
}
private void rangeCheckForAdd(int index) throws nameError{
if(index<0 || index >size()) {
throw new nameError("插入index位置异常");
}
}
private void rangeCheck(int index) throws nameError {
if(index<0 || index >size()) {
throw new nameError("删除index位置异常");
}
}
public int size() {
return this.usedSize;
}
private void sub(int index) {
for(int i = index;i<usedSize;i++) {
elementData[i] = elementData[i+1];
}
elementData[usedSize-1] = null;
usedSize--;
}
// 删除 index 位置的 元素
public E remove(int index) {
rangeCheck(index);
E oldvalue = (E) elementData[index];
// 这里elementData为 Object类型要强转才能赋值
sub(index);
return oldvalue;
}
// 遍历寻找 数组中e 的元素是否存在
private int a(E e) {
for(int i = 0;i<usedSize;i++) {
if(elementData[i].equals(e)) {
return i;
}
}
return -1;
}
public void remove(E e) throws doesnotexistError {
int ret = a(e);
if(ret == -1) {
throw new doesnotexistError("要删除的元素不存在");
}else {
sub(ret);
}
}
public void rangeCheck2(int index) throws nameError {
if(index < 0 || index > size()) {
throw new nameError("要获取信息的位置不合法");
}
}
public E get(int index) {
rangeCheck2(index);
return (E)this.elementData[index];
}
public E set(int index , E e) {
rangeCheck2(index);
E oldvalue = (E) elementData[index];
elementData[index] = e;
return oldvalue;
}
public void clear() {
for(int i = 0;i<usedSize;i++) {
elementData[i] = null;
}
usedSize = 0;
}
@Override
public String toString() {
return "MyArrayList{" +
"elementData=" + Arrays.toString(elementData) +
", usedSize=" + usedSize +
'}';
}
}
剩下的方法 可以自行看 源码实现,这里 只完成常用的 几种方法。
最后我们来用ArrayList 实现一副扑克牌
//扑克牌
class Card{
// 数字
private int point;
// 花色
private String flowerColor;
public Card(int point,String flowerColor) {
this.point = point;
this.flowerColor = flowerColor;
}
@Override
public String toString() {
return "["+this.flowerColor+" : " +this.point+" ]";
}
}
public class Test2 {
public static final String[] suits = {"♥","♣","♦","♠"};
// 创建一副牌
public static ArrayList<Card> byCard() {
ArrayList<Card> list = new ArrayList<>();
for(int i = 0;i<4;i++) {
// 4 中 花色 13 中 数字 1 - 13 除去大小王
for (int j = 1; j <=13 ; j++) {
String suit = suits[i];
Card card = new Card(j,suit);
list.add(card);
//这里也可 这样些,
// list.add(new Card(j,suits[i]));
}
}
return list;
}
// 换牌
private static void swap(List<Card>list,int i,int ret) {
//其实 这里就是我们常用的交换元素
// 只是 我们 要在 list 中 来获取 i 和 ret 的 信息,
// 在通过 set 来交换
// 原型 Card tmp = list[i]
Card tmp = list.get(i);
// linst[i] = list[ret]
list.set(i,list.get(ret));
//list[ret] = tmp;
list.set(ret,tmp);
}
// 洗牌
public static void shuffle(List<Card> list) {
System.out.println("开始洗牌");
System.out.println(list);
int size = list.size() - 1;
// 这里 我们可以先拿到最后一个元素的下标,
for(int i = size;i>0;i--) {
Random random = new Random();
int ret =random.nextInt(i);
swap(list,i,ret);
}
System.out.println("洗牌完成");
System.out.println(list);
}
public static void main(String[] args) {
ArrayList<Card> list = new ArrayList();
list = byCard();
System.out.println(list);
shuffle(list);
// System.out.println(list);
ArrayList<ArrayList<Card>> hand = new ArrayList<>();
ArrayList<Card> hand1 = new ArrayList<>();
ArrayList<Card> hand2 = new ArrayList<>();
ArrayList<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 = list.remove(0);
hand.get(j).add(card);
}
}
System.out.println("第一个人的牌:"+hand1);
System.out.println("第二个人的牌:"+hand2);
System.out.println("第三个人的牌:"+hand3);
}
}
最后我们 在来 巩固一下学到ArrayList<Arraylist<>> list = new Array<>();
杨辉三角形
相比大家都和熟悉 杨辉三角形吧 ,不就是一个直角三角形,j == 0 和 i== j 的位置赋值为 1,其他位置 arr[i][j] == arr[i-1][j]+arr[i-1][j-1] 这样的思路
然后这里我们来实践一下
class Solution {
public List<List<Integer>> generate(int numRows) {
// 这里 就 创建了一个ret 变量 相当于 一个二维数组 arr[i][j]
List<List<Integer>> ret = new ArrayList<>();
// 将第一行 的 为一个 元素 j == 0 的 地方放入 1
List<Integer> list = new ArrayList<>();
list.add(1);
// 这一行 放完 就放入我们的二维数组中,
ret.add(list);
for(int i = 1;i<numRows;i++) {
// 没一行的 第一列 就是 j = 0 的 地方放入 1
List<Integer> list2 = new ArrayList<>();
list2.add(1);
//这一步就先当与 得到 i - 1 行 的 信息
List<Integer> preRow = ret.get(i-1);
for(int j = 1;j<i;j++) {
// 这里 不就是 arr[i][j] = arr[i-1][j]+arr[i-1][j-1]
int nums = preRow.get(j)+preRow.get(j-1);
将他放入顺序表中
list2.add(nums);
}
最后将 最后一个 1 假如 ,就是 i == j 的 地方
list2.add(1);
别忘记 要放进我们的二维数组中,
ret.add(list2);
}
return ret;
}
}