赞
踩
泛型在上篇文章集合框架即背后的数据结构中已经降到了,而且用起来了。
再开始之前先要了解两个概念
- 首先,我们在学习多态过程中已知一个前提,基类的引用可以指向子类的对象。
- 其次,我们也已知 Object 是 java 中所有类的祖先类。
顺序表的功能不是重点,我们在这里只是粗略实现一下顺序表的功能,重点在泛型
class MyArrayList{ private int[] elem;// 建立数组 private int usedSize;// 有效元素个数 public MyArrayList(){// 构造方法 this.elem = new int[10];// 默认数组初始容量为 10 } public void add(int val){// 添加元素 this.elem[usedSize] = val; } public int get(int pos){// 得到指定位置的元素 return this.elem[pos]; } } public class Test { }
但是这个代码并不通用,只能存储一种数据类型(int)。
再来讨论一下输出
再来掰扯一些细节问题
1. 泛型是作用在编译期间的一种机制,即运行期间没有泛型的概念。
2. 泛型代码在运行期间,就是我们上面提到的,利用 Object 达到的效果(这里不是很准确,以后会做说明)。
3. 泛型是为了解决某些容器、算法等代码的通用性而引入,并且能在编译期间做类型检查。
4. 泛型利用的是 Object 是所有类的祖先类,并且父类的引用可以指向子类对象的特定而工作。
5. 泛型是一种编译期间的机制,即 MyArrayList 和 MyArrayList 在运行期间是一个类型。
6. 泛型是 java 中的一种合法语法,标志就是尖括号 <>
Object 引用可以指向任意类型的对象,但有例外出现了,8 种基本数据类型不是对象,那岂不是刚才的泛型机制要
失效了?
实际上也确实如此,为了解决这个问题,java 引入了一类特殊的类,即这 8 种基本数据类型的包装类,在使用过程
中,会将类似 int 这样的值包装到一个对象中去。
基本就是类型的首字母大写,除了 Integer 和 Character
基本数据类型 | 包装类 |
---|---|
byte | Byte |
short | Short |
int | Integer |
long | Long |
float | Float |
double | Double |
char | Character |
boolean | Boolean |
当我们需要将某种类型的数据转换成其它的数据类型时,需要通过某种来达到目的。
而包装类就是这些功能的集大成者,包含多种类型转换方法和其他功能。
装箱 / 装包 :就是把简单类型数据 变为 包装类类型数据
拆箱 / 拆包 : 就是把包装类类型数据 变为 简单类型数据
借机在这里给大家讲一个面试题
小窗口中显示的是 List接口还实现了那几个接口,或者说是List接口的父类接口
之所以教你们弹出这个框子,是为了方便加下来的讲解,让我们来看看ArrayLis图表
1. ArrayList实现了RandomAccess接口,表明ArrayList支持随机访问
2. ArrayList实现了Cloneable接口,表明ArrayList是可以clone的
3. ArrayList实现了Serializable接口,表明ArrayList是支持序列化的(序列化:把一个对象转换成字符串)
4. 和Vector不同,ArrayList不是线程安全的,在单线程下可以使用,在多线程中可以选择Vector或者
CopyOnWriteArrayList
5. ArrayList底层是一段连续的空间,并且可以动态扩容,是一个动态类型的顺序表
可参考顺序表 和 链表 - 顺序表部分来了解ArrayList的常用功能,和 合框架即背后的数据结构了解一下常用接口的基本性质和功能。
public class TestDemo { public static void main(String[] args) { ArrayList<String> list = new ArrayList<>(); list.add("a"); list.add("b"); list.add("c");// 添加List元素 System.out.println(list); System.out.println("==============="); list.add(1,"g");// 在List指定位置中添加元素 System.out.println(list); System.out.println("========"); List<String> list1 = new ArrayList<>(); list1.add("x"); list1.add("y"); list.addAll(list1);// 将一个list1 整体添加 list中 System.out.println(list); } }
取出 elementData 的元素之前,要强转类型。
public static void main(String[] args) {
List<Integer> list = new ArrayList<>();
for (int i = 0; i < 100; i++) {
list.add(i);
}
}
首先我们认为这个代码是没有缺陷的,但是因为ArrayList 底层的数组是有一定大小的,那么存放数组的过程中,一定会涉及到扩容,
前面我们讲到ArrayList 有三种方法,现在使用的是不带参数的,也就是说ArrayList 底层的数组初始容量为零。 那么第一个问题就出现了: 既然数组的容量是为零,那么它怎么还可以存入数据?
第二个问题: 假设数组初始化容量为10,超过了10,就需要扩容。而且扩容操作时在代码底层执行,是看不见的,也就是说ArrayList在存储数据,隐式的进行扩容操作,那么它的扩容机制是怎样的?
&ensp;
// E 是数据类型
方法 | 解释 |
---|---|
boolean add(E e) | 尾插 e |
void add(int index,E element) | 将e 插入到index位置 |
boolean 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,Eelement) | 将下标为index的元素,置换为 element |
void clear() | 清空 |
boolean contains(Object o) | 判断 o 是否在线性表中 |
int indexOf(Object o) | 从左往右 返回第一个 o 的下标 |
int lastIndexOf(Object o) | 返回最后一个o的下标 (从右往左 返回第一个 o 的下标) |
List subList(int fromIndex,int tolndex) | "截取"部分list |
&ensp;
效果图
基本功能都实现了,除了subList 没有实现,因为它涉及反射方面的知识,目前还博主还没学到。到后面写到。
另外 你有没有发现。其实你想要模拟顺序表的功能实现,最好的老师就是原码。以后大家在学习某一个数据结构时,先看它的原码,它会帮助你理解并掌握。
其实这次是模拟,只是略微细腻一丢丢,我们还没处理类型转换 和 toString 方法的从写,因为我还有写问题不知道怎么解决,所以我按照自己的想法写了一个,原码的toString还有一些地方,还没理解透。
目的:
1.构造一副扑克牌
2.揭牌
不包含打牌规则哦~,除非你想让我四。。。
1.点数
2.花色
注意:我们这副扑克,不包含大小王。
假设现在有三个人玩同花顺,也就是说 每个人 手上 会拿到 5 张牌。
import java.util.ArrayList; import java.util.List; import java.util.Random; class Card{ private int point; private String flowerColor; public Card(int point, String flowerColor) { this.point = point; this.flowerColor = flowerColor; } public int getPoint() { return point; } public void setPoint(int point) { this.point = point; } public String getFlowerColor() { return flowerColor; } public void setFlowerColor(String flowerColor) { this.flowerColor = flowerColor; } @Override public String toString() { return "{ " +flowerColor +" "+point+" }"; } } public class PlayingCard { // 定义 扑克牌的花色 private static final String[] flowerColors = {"♥","♠","♦","♣"}; // 创建一副扑克 public static List<Card> newCard() { ArrayList<Card> cards = new ArrayList<>(); for (int i = 0; i < 4; i++) {// 4种花色 for (int j = 1; j <= 13; j++) {// 尖 到 k 一共13个点数 cards.add(new Card(j,flowerColors[i])); } } return cards; } // 洗牌 public static void shuffle(List<Card> list){ // 牌数是52,数组下标就是51 // 从最后一张牌开始,随机与 本身 或者 本身前面的任意一张牌 交换位置。 // 这样的做交换性 比 从开头洗 的 打乱顺序的 效率 高。 for (int i = list.size()-1; i >0 ; i--) { // Random 是一个生成随机数的类 Random random = new Random(); // 通过 Random的引用 random 去调用 nextInt() 方法。 // random.nextInt() 方法,根据括号中的值,随机生成 0 ~ 括号中的值 int rand = random.nextInt(i); // 将 第 i 张牌 , 与 自身 或者 自身前面的任意一张牌的下标 丢给 swap方法 // 让它去交换位置 swap(list,i,rand); } } // 交互式洗牌模式 private static void swap(List<Card> list,int i,int j){ // 我们现在是面向对象,ArrayList虽然底层是一个数组,但是需要使用方法,才能操作数组的元素 // 并不能像数组一样,直接操作 // Card tmp = list[i]; Card tmp = list.get(i);// 获取 顺序表中,对应下标的元素 // list[i] = list[j]; list.set(i,list.get(j));// 将 j下标的元素,赋给 i 下标的元素, // list[j] = tmp; list.set(j,tmp); } public static void main(String[] args) { System.out.println("======一副买来拆的牌=========="); List<Card> list = newCard(); System.out.println(list); System.out.println("======== 洗牌 ========="); shuffle(list); System.out.println(list); System.out.println("======== 发牌,3个人轮着发,每个人5张牌========="); ArrayList<ArrayList<Card>> player = new ArrayList<>(); // 这行代码 就是 一个二维数组, // 首先我们有一个player, player 的每个元素 都是 ArrayList<Card> 类型。 // 也就是说每个元素就是一个顺序表,也可以说是一个一维数组。 // 你也可以这么理解 第一个 ArrayList 是用来记录有 玩家的方位/顺序表的地址/数组的地址 // 第二个ArrayList 就是 每个玩家手上牌的情况/数组的元素情况/顺序表的底层数组元素情况。 // 你可以 把 player 看作牌桌,等待三位玩家的入场。 // 打牌三人组 ArrayList<Card> playerOne = new ArrayList<>(); ArrayList<Card> playerTwo = new ArrayList<>(); ArrayList<Card> playerThree = new ArrayList<>(); // 将三位玩家的信息,加载到 player 当中 player.add(playerOne); player.add(playerTwo); player.add(playerThree); for (int i = 0; i < 5; i++) {// 发 5 轮牌 for (int j = 0; j < 3; j++) {// 每个人 轮着发,最终每个人5张牌 Card card = list.remove(0); player.get(j).add(card); } } // 打印每个人的手牌 System.out.println("playerOne的手牌:"+ playerOne); System.out.println("playerTwo的手牌:"+playerTwo); System.out.println("playerThree的手牌:"+playerThree); System.out.println("list 剩余的牌:"+list); } // public static void main1(String[] args) { // Card card = new Card(3,"♠"); // System.out.println(card); // } }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。