Java中關(guān)于泛型、包裝類及ArrayList的詳細(xì)教程
一、泛型
1.1 泛型類的定義
// 1. 尖括號(hào) <> 是泛型的標(biāo)志
// 2. E 是類型變量(Type Variable),變量名一般要大寫
// 3. E 在定義時(shí)是形參,代表的意思是 MyArrayList 最終傳入的類型,但現(xiàn)在還不知道
public class MyArrayList<E> {
private E[] array;
private int size;
}
泛型類可以一次有多個(gè)類型變量,用逗號(hào)分割。
- 泛型是作用在編譯期間的一種機(jī)制,即運(yùn)行期間沒有泛型的概念。
- 泛型代碼在運(yùn)行期間,利用 Object 達(dá)到的效果(這里不是很準(zhǔn)確)。
- 泛型的意義:自動(dòng)對(duì)類型進(jìn)行檢查
1.2 泛型類的使用
示例:
class MyArrayList<E>{// <E>代表當(dāng)前類是一個(gè)泛型類,此時(shí)的E就是一個(gè)占位符而已
private E[] elem;
private int usedSize;
public MyArrayList() {
// this.elem = elem;
this.elem = (E[])new Object[10];//這樣的寫法不是十分正確
}
public void add(E val){
this.elem[usedSize] = val;
usedSize++;
}
public E get(int pos){
return this.elem[pos];
}
}
public class test02 {
public static void main(String[] args) {
//泛型中尖括號(hào)里面的內(nèi)容不參與類型的組成
MyArrayList<String> myArrayList = new MyArrayList<>();
System.out.println(myArrayList);
MyArrayList<Integer> myArrayList1 = new MyArrayList<>();
System.out.println(myArrayList1);
MyArrayList<Boolean> myArrayList2 = new MyArrayList<>();
System.out.println(myArrayList2);
}
public static void main2(String[] args) {
MyArrayList<String> myArrayList = new MyArrayList<>();
myArrayList.add("ni");//自動(dòng)對(duì)類型進(jìn)行檢查,不是字符串類型就會(huì)報(bào)錯(cuò)
myArrayList.add("n");
String ret = myArrayList.get(1);//自動(dòng)對(duì)類型進(jìn)行強(qiáng)制類型轉(zhuǎn)換
System.out.println(ret);
}
}
1.3 泛型總結(jié)
- 泛型是為了解決某些容器、算法等代碼的通用性而引入,并且能在編譯期間做類型檢查。
- 泛型利用的是
Object是所有類的祖先類,并且父類的引用可以指向子類對(duì)象的特定而工作。 - 泛型是一種編譯期間的機(jī)制,即
MyArrayList<Integer>和MyArrayList<String>在運(yùn)行期間是一個(gè)類型。即泛型中尖括號(hào)里面的內(nèi)容不參與類型的組成。 - 泛型是
java中的一種合法語法,標(biāo)志就是尖括號(hào)<>。
二、包裝類
2.1基本數(shù)據(jù)類型和包裝類直接的對(duì)應(yīng)關(guān)系
| 基本數(shù)據(jù)類型 | 包裝類 |
|---|---|
| byte | Byte |
| short | Short |
| int | Integer |
| long | Long |
| float | Float |
| double | Double |
| char | Character |
| boolean | Boolean |
基本就是類型的首字母大寫,除了 Integer 和 Character。
2.2 包裝類的使用,裝箱(boxing)和拆箱(unboxing)
裝箱(裝包):把簡(jiǎn)單類型變成包裝類型。 拆箱(拆包):把包裝類型變成簡(jiǎn)單類型。
public static void main(String[] args) {
Integer a = 123;//裝箱 裝包(隱式的)
//Integer 的范圍[-128,127];
int b= a;//拆箱 拆包(隱式的)
System.out.println("a="+a+" "+ "b="+ b);
System.out.println("===============");
Integer a2 = Integer.valueOf(123);//顯式的裝包
Integer a3 = new Integer(123);//顯式的裝包
int b2 = a2.intValue();//顯式的拆包
double d = a2.doubleValue();//顯式的拆包
int i = 10;//顯式的初始化
}
2.3 自動(dòng)裝箱(autoboxing)和自動(dòng)拆箱(autounboxing)
在使用過程中,裝箱和拆箱帶來不少的代碼量,所以為了減少開發(fā)者的負(fù)擔(dān),java 提供了自動(dòng)機(jī)制。 自動(dòng)裝箱和自動(dòng)拆箱是工作在編譯期間的一種機(jī)制。
int b2 = a2.intValue();//顯式的拆包 double d = a2.doubleValue();//顯式的拆包
三、List 的使用
3.1 ArrayList簡(jiǎn)介
在集合框架中,ArrayList是一個(gè)普通的類,實(shí)現(xiàn)了List接口,具體框架圖如下:

ArrayList實(shí)現(xiàn)了RandomAccess接口,表明ArrayList支持隨機(jī)訪問。ArrayList實(shí)現(xiàn)了Cloneable接口,表明ArrayList是可以clone的。ArrayList實(shí)現(xiàn)了Serializable接口,表明ArrayList是支持序列化的。- 和
Vector不同,ArrayList不是線程安全的,在單線程下可以使用,在多線程中可以選擇Vector或者CopyOnWriteArrayList。 ArrayList底層是一段連續(xù)的空間,并且可以動(dòng)態(tài)擴(kuò)容,是一個(gè)動(dòng)態(tài)類型的順序表。 3.2 ArrayList的構(gòu)造
public static void main(String[] args) {
// ArrayList創(chuàng)建,推薦寫法
// 構(gòu)造一個(gè)空的列表
List<Integer> list1 = new ArrayList<>();
// 構(gòu)造一個(gè)具有10個(gè)容量的列表
List<Integer> list2 = new ArrayList<>(10);
list2.add(1);
list2.add(2);
list2.add(3);
// list2.add("hello"); // 編譯失敗,List<Integer>已經(jīng)限定了,list2中只能存儲(chǔ)整形元素
// list3構(gòu)造好之后,與list2中的元素一致
//使用另外一個(gè)ArrayList對(duì)list3進(jìn)行初始化
ArrayList<String> list3 = new ArrayList<>(list2);
// 避免省略類型,否則:任意類型的元素都可以存放,使用時(shí)將是一場(chǎng)災(zāi)難
List list4 = new ArrayList();
list4.add("111");
list4.add(100);
}
3.3 ArrayList的遍歷
ArrayList 可以使用三種方式遍歷:for循環(huán)+下標(biāo)、foreach、使用迭代器。
public static void main(String[] args) {
List<String> list = new ArrayList<>();
ArrayList<String> list2 = new ArrayList<>();
list2.add("hello");
list2.add("world");
System.out.println(list2);//打印方式一
System.out.println("============");
for (int i = 0; i < list2.size(); i++) {//打印方式二
System.out.print(list2.get(i)+" ");
}
System.out.println();
System.out.println("==========");
for (String s:list2) {//打印方式三
System.out.print(s+" ");
}
System.out.println();
System.out.println("====迭代器打印方式1======");
Iterator<String> it = list2.iterator();
while (it.hasNext()){
System.out.print(it.next()+" ");
}
System.out.println();
System.out.println("=====迭代器打印方式2=====");
ListIterator<String> it2 = list2.listIterator();//打印方式四,使用迭代器進(jìn)行打印
while (it2.hasNext()){
System.out.print(it2.next()+" ");
}
}
輸出結(jié)果:

3.4 ArrayList的常見操作
3.4.1 刪除 index 位置元素(remove)
E remove(int index) //刪除 index 位置元素
示例:
public static void main(String[] args) {
ArrayList<String> list2 = new ArrayList<>();
list2.add("hello");
list2.add("bit");
list2.add("haha");
Iterator<String> it = list2.iterator();
while (it.hasNext()) {
String ret = it.next();
if(ret.equals("hello")) {
it.remove();//首先需要使用next方法迭代出集合中的元素 ,然后才能調(diào)用remove方法
}else {
System.out.print(ret + " ");
}
}
System.out.println();
System.out.println("========迭代器List相關(guān)打印==========");
ListIterator<String> it2 = list2.listIterator();
while (it2.hasNext()) {
String ret = it2.next();
if(ret.equals("hello")) {
it2.remove();//首先需要使用next方法迭代出集合中的元素 ,然后才能調(diào)用remove方法
}else {
System.out.print(ret + " ");
}
}
}
輸出結(jié)果:

3.4.1尾插(add)
boolean add(E e) //尾插 e
示例:
public static void main(String[] args) {
ArrayList<String> list2 = new ArrayList<>();
//CopyOnWriteArrayList<String> list2 = new CopyOnWriteArrayList<>();
list2.add("hello");
list2.add("bit");
list2.add("haha");
//Iterator迭代器沒有add方法
/* Iterator<String> it = list2.iterator();
while (it.hasNext()) {
String ret = it.next();
if(ret.equals("hello")) {
it.add();//沒有add方法
}else {
System.out.print(ret + " ");
}
}*/
//使用ListIterator迭代器的方法添加元素,會(huì)將元素添加到其緊跟著的后面
ListIterator<String> it2 = list2.listIterator();
while (it2.hasNext()) {
String ret = it2.next();
if(ret.equals("bit")) {
it2.add("world");
//若使用list2.add()就會(huì)拋出異常,
//但是將上面的list2變成CopyOnWriteArrayList<String>類型就不會(huì)報(bào)錯(cuò)。
//就可以使用list2.add()的方法就可以
// list2.add("world");
}else {
System.out.print(ret + " ");
}
}
System.out.println("=================");
System.out.println(list2);
}
運(yùn)行結(jié)果:

ArrayList<String> list2 = new ArrayList<>();//不是線程安全的
迭代時(shí)使用的是it2.add("world");
CopyOnWriteArrayList<String> list2 = new CopyOnWriteArrayList<>();//是線程安全的
迭代時(shí)使用的是list2.add("world");
3.4.2將元素插入到list中的指定位置add
3.4.3 尾插一個(gè)ArrayList中的所有元素到另一個(gè)ArrayList當(dāng)中(addAll)
方法:
void add(int index, E element) //將 e 插入到 index 位置 boolean addAll(Collection<? extends E> c) //尾插 c 中的元素
示例:
public static void main(String[] args) {
ArrayList<String> list2 = new ArrayList<>();
list2.add("a");
list2.add("b");
list2.add("c");
list2.add("d");
list2.add("d");
System.out.println(list2);//add方法默認(rèn)將字符串放到數(shù)組的最后一個(gè)位置
list2.add(0,"hello");//在list2的零下標(biāo)位置加入字符串"hello"
System.out.println(list2);
ArrayList<String> list3 = new ArrayList<>();
list3.add("加入");
list2.addAll(list3);//將list3中的所有元素放到list2中
System.out.println(list2);
}
輸出結(jié)果:

3.4.4 刪除指定下標(biāo)位置的元素remove(int index)
3.4.5刪除list中第一次出現(xiàn)的某元素remove(Object o)
3.4.6 獲取某下標(biāo)位置的元素get()
3.4.7 將指定下標(biāo)位置的元素設(shè)置為指定值set()
方法:
E remove(int index) //刪除 index 位置元素 boolean remove(Object o) //刪除遇到的第一個(gè) o E get(int index) //獲取下標(biāo) index 位置元素 E set(int index, E element) //將下標(biāo) index 位置元素設(shè)置為 element
示例:
public static void main(String[] args) {
ArrayList<String> list2 = new ArrayList<>();
list2.add("a");
list2.add("b");
list2.add("c");
list2.add("d");
list2.add("d");
System.out.println(list2);//add方法默認(rèn)放到數(shù)組的最后一個(gè)位置
String ret = list2.remove(0);//刪除0下標(biāo)位置元素
System.out.println(list2);
boolean ret1 = list2.remove("d"); //刪除遇到的第一個(gè)"d"
//如果要?jiǎng)h除的數(shù)list2中沒有則返回false
System.out.println(ret1); //true
String ret2 = list2.get(2);//獲取下標(biāo)為2位置的元素
System.out.println(ret2);//d
String ret3 = list2.set(2,"hello");//將下標(biāo)為2位置的元素改為"hello"
System.out.println(ret3);//d
System.out.println(list2);//[b, c, hello]
輸出結(jié)果:

3.4.8 清空線性表中的元素clear()
3.4.9 判斷線性表中是否包含某元素 contains()
3.4.10 返回第一個(gè) o 所在下標(biāo)位置 indexOf()
3.4.11 返回最后一個(gè)o出現(xiàn)的下標(biāo)位置 lastIndexOf()
3.4.12 截取部分 list 中的部分元素 subList()
方法:
void clear() //清空 boolean contains(Object o) //判斷 o是否在線性表中 int indexOf(Object o) //返回第一個(gè) o 所在下標(biāo) int lastIndexOf(Object o) //返回最后一個(gè) o 的下標(biāo) List<E> subList(int fromIndex, int toIndex) //截取部分 list
示例:
public static void main(String[] args) {
ArrayList<String> list2 = new ArrayList<>();
list2.add("a");
list2.add("b");
list2.add("c");
list2.add("d");
list2.add("d");
System.out.println(list2);//add方法默認(rèn)放到數(shù)組的最后一個(gè)位置
System.out.println(list2.indexOf("a"));//0 判斷a的下標(biāo)位置
System.out.println(list2.lastIndexOf("d"));//4 判斷最后一個(gè)d出現(xiàn)的下標(biāo)位置
List<String> sub = list2.subList(1,3);//[b, c] 截取下標(biāo)為[1,3)位置的元素,截取的區(qū)間范圍為左閉右開的
System.out.println(sub);//[b, c]
System.out.println(list2);//[a, b, c, d, d]
System.out.println("===================");
sub.set(0,"p");
System.out.println(sub);//[p, c]
System.out.println(list2);//[a, p, c, d, d]
System.out.println(list2.contains("c"));//true //判斷l(xiāng)ist2當(dāng)中是否包含字符"c"
list2.clear();//將list2中的元素清空
System.out.println(list2);
輸出結(jié)果:

四、ArrayList的擴(kuò)容機(jī)制
如果ArrayList調(diào)用不帶參數(shù)的構(gòu)造方法,那么順序表的大小為0,當(dāng)?shù)谝淮?code>add的時(shí)候,整個(gè)順序表才變?yōu)榱?code>10;當(dāng)這個(gè)10放滿了,開始擴(kuò)容,以1.5倍的方式進(jìn)行擴(kuò)容。 如果調(diào)用的是給定容量的構(gòu)造方法,那么順序表的大小就是給定的容量,放滿了還是以1.5倍進(jìn)行擴(kuò)容。
到此這篇關(guān)于Java中關(guān)于泛型、包裝類及ArrayList的詳細(xì)教程的文章就介紹到這了,更多相關(guān)java泛型包裝類ArrayList內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java8新特性之lambda的作用_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理
我們期待了很久lambda為java帶來閉包的概念,但是如果我們不在集合中使用它的話,就損失了很大價(jià)值?,F(xiàn)有接口遷移成為lambda風(fēng)格的問題已經(jīng)通過default methods解決了,在這篇文章將深入解析Java集合里面的批量數(shù)據(jù)操作解開lambda最強(qiáng)作用的神秘面紗。2017-06-06
Java如何實(shí)現(xiàn)遠(yuǎn)程文件下載到本地目錄
本文介紹了如何使用Java來實(shí)現(xiàn)遠(yuǎn)程文件的下載功能,主要通過HTTPS路徑下載文件到本地目錄,詳細(xì)介紹了相關(guān)代碼和測(cè)試步驟,并提供了實(shí)際案例供參考,本文旨在幫助需要實(shí)現(xiàn)文件下載功能的開發(fā)者快速掌握核心技術(shù)2024-10-10
前端如何調(diào)用后端接口進(jìn)行數(shù)據(jù)交互詳解(axios和SpringBoot)
一般來講前端不會(huì)給后端接口,而是后端給前端接口的情況比較普遍,下面這篇文章主要給大家介紹了關(guān)于前端如何調(diào)用后端接口進(jìn)行數(shù)據(jù)交互的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2023-03-03
Java實(shí)現(xiàn)CORS跨域請(qǐng)求的實(shí)現(xiàn)方法
本篇文章主要介紹了Java實(shí)現(xiàn)CORS跨域請(qǐng)求的實(shí)現(xiàn)方法,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-09-09

