目录
2.2 包装类的使用,装箱(boxing)和拆箱(unboxing)
2.3 自动装箱(autoboxing)和自动拆箱(autounboxing)
1.泛型
1.1 泛型类的定义
.
尖括号
<>
是泛型的标志
2.E
是类型变量
(TypeVariable)
,变量名一般要大写
3.E
在定义时是形参,代表的意思是
MyArrayList
最终传入的类型,但现在还不知道。
public class MyArrayList<E> {
private E[] array;
private int size;
//.....
}
注意:泛型类可以一次有多个类型变量,用逗号分割。
1.2 泛型背后作用时期和背后的简单原理
1.
泛型是作用在编译期间的一种机制,即运行期间没有泛型的概念。
2.
泛型代码在运行期间,利用
Object
达到的效果。
1.3 泛型类的使用
//定义了一个元素是Book引用的MyArrayList
MyArrayList<Book> books = new MyArrayList<Book>();
books.add(new Book());
//会产生编译错误,Person类型无法转换为Book类型
books.add(new Person());
//不需要做类型转换
Book book = book.get(0);
//不需要做类型转换
//会产生编译错误,Book类型无法转换为Person类型
Person person = book.get(0);
通过以上代码,我们可以看到泛型类的一个使用方式:只需要在所有类型后边跟尖括号,并且尖括号内是真正的类型,即 E
可以看作的最后的类型。
注意:
Book
只能想象成
E
的类型,但实际上
E
的类型还是
Object
。
1.4 泛型总结
1.
泛型是为了解决某些容器、算法等代码的通用性而引入,并且能在编译期间做类型检查。
2.
泛型利用的是
Object
是所有类的祖先类,并且父类的引用可以指向子类对象的特定而工作。
3.
泛型是一种编译期间的机制,即
MyArrayList<Person>
和
MyArrayList<Book>
在运行期间是一个类型。
4.
泛型是
java
中的一种合法语法,标志就是尖括号
<>
2.包装类(Wrapper Class)
Object
引用可以指向任意类型的对象,但有例外出现了,
8
种基本数据类型不是对象,那岂不是刚才的泛型机制要失效了?
实际上也确实如此,为了解决这个问题,
java
引入了一类特殊的类,即这
8
种基本数据类型的包装类,在使用过程中,会将类似 int
这样的值包装到一个对象中去。
2.1 基本数据类型和包装类直接的对应关系
基本数据类型
|
包装类 |
byte
|
Byte |
short
|
Short |
int | Integet |
long | Long |
float | Float |
double | Double |
char | CHaracter |
boolean | Boolean |
基本就是类型的首字母大写,除了
Integer
和
Character
。
2.2 包装类的使用,装箱(boxing)和拆箱(unboxing)
int i = 10;
// 装箱操作,新建一个 Integer 类型对象,将 i 的值放入对象的某个属性中
Integer ii = Integer.valueOf(i);
Integer ij = new Integer(i);
// 拆箱操作,将 Integer 对象中的值取出,放到一个基本数据类型中
int j = ii.intValue();
2.3 自动装箱(autoboxing)和自动拆箱(autounboxing)
可以看到在使用过程中,装箱和拆箱带来不少的代码量,所以为了减少开发者的负担,java 提供了自动机制。
int i = 10;
Integer ii = i; // 自动装箱
Integer ij = (Integer)i; // 自动装箱
int j = ii; // 自动拆箱
int k = (int)ii; // 自动拆箱
注意:
自动装箱和自动拆箱是工作在编译期间的一种机制。
3. List 的使用
3.1 常见方法
(1)List
(线性表):
方法
|
方法
|
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)
|
E
get
(int index)
|
E
set
(int index, E element)
|
将下标
index
位置元素设置为 element
|
void
clear
()
|
清空 |
boolean
contains
(Object o)
|
判断
o
是否在线性表中
|
int
indexOf
(Object o
|
返回第一个
o
所在下标
|
int
lastIndexOf
(Object o)
|
返回最后一个 o 所在下标 |
List<E>
subList
(int fromIndex, int toIndex)
|
截取部分 list |
(2)ArrayList
(顺序表) :
方法 | 解释 |
ArrayList
()
|
无参数构造 |
ArrayList(Collection<? extends E> c) |
利用其他
Collection
构建
ArrayList
|
ArrayList(int intialCapacity) | 指定顺序表初始容量 |
LinkeList (链表)
方法 | 解释 |
LinkeList ( ) | 无参数构造 |
3.2 代码示例
尾插、获取下标 i 的元素
import java.util.ArrayList;
import java.util.List;
public class ListTest {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
//尾插
list.add("we");
list.add("are");
list.add("java");
list.add("student");
System.out.println("尾插: "+ list);//以字符串打印
//遍历打印,获取下标 i 的元素
System.out.print("获取下标 i 的元素 :");
for (int i = 0; i < list.size(); i++) {
System.out.print(list.get(i)+" ");
}
}
}
修改下标 i 的值,截取部分字符串
import java.util.ArrayList;
import java.util.List;
public class ListTest {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
//尾插
list.add("we");
list.add("are");
list.add("java");
list.add("student");
//将下标 i 位置元素设置为 element
list.set(1,"element");
System.out.println(list);
// 截取部分 [1, 3),遵循闭右开原则
List<String> list1 = list.subList(1,3);
System.out.println(list1);
}
}
重新构造、引用转换
public class ListTest {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
//尾插
list.add("we");
list.add("are");
list.add("java");
list.add("student");
//重新构造
List<String> list3 = new ArrayList<>(list);
System.out.println(list3);
//引用转换
ArrayList<String> arrayList = new ArrayList<>(list);
System.out.println(arrayList);
ArrayList<String> arrayList1 =( ArrayList<String>)(list);
System.out.println(arrayList1);
}
}
3.3 综合练习
扑克牌
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.Callable;
class Card {
private int rank;//数字
private String suit;
public Card(int rank, String suit) {
this.rank = rank;
this.suit = suit;
}
@Override
public String toString() {
return "["+this.suit+":"+this.rank+"]";
}
}
public class CardTest {
private static final String[] suits = {"♥","♠","♣","♦"};
//买牌
public static List<Card> buyCard() {
ArrayList<Card> cards = new ArrayList<>();
for (int i = 0; i < 4; i++) {
for (int j = 1; j <= 13; j++) {
/*String suit = suits[i];
int rank = j;
Card card = new Card(rank,suit);
cards.add(card);*/
cards.add(new Card(j,suits[i]));
}
}
return cards;
}
//洗牌
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);
}
public static void shuffle(List<Card> cards) {
int size = cards.size();
for (int i = size-1; i > 0; i--) {
Random random = new Random();
int rand = random.nextInt(i);
swap(cards,i,rand);
}
}
public static void main(String[] args) {
List<Card> cards = buyCard();
System.out.println("买牌: "+ cards );
shuffle(cards);
System.out.println("洗牌:"+cards);
System.out.println("揭牌:3个人每个人轮流揭5张牌");
ArrayList<List<Card>> hand = new ArrayList<>();
List<Card> hand2 = new ArrayList<>();
List<Card> hand3 = new ArrayList<>();
List<Card> hand1 = 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("第1个人的牌:"+hand1);
System.out.println("第2个人的牌:"+hand2);
System.out.println("第3个人的牌:"+hand3);
System.out.println("剩下的牌:"+cards);
}
}