最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java數(shù)據(jù)結(jié)構(gòu)之ArrayList從順序表到實(shí)現(xiàn)

 更新時(shí)間:2023年04月28日 08:30:12   作者:ZIYE_190  
Java中的ArrayList是一種基于數(shù)組實(shí)現(xiàn)的數(shù)據(jù)結(jié)構(gòu),支持動(dòng)態(tài)擴(kuò)容和隨機(jī)訪問(wèn)元素,可用于實(shí)現(xiàn)順序表等數(shù)據(jù)結(jié)構(gòu)。ArrayList在內(nèi)存中連續(xù)存儲(chǔ)元素,支持快速的隨機(jī)訪問(wèn)和遍歷。通過(guò)學(xué)習(xí)ArrayList的實(shí)現(xiàn)原理和使用方法,可以更好地掌握J(rèn)ava中的數(shù)據(jù)結(jié)構(gòu)和算法

1 ArrayList

在集合框架中,ArrayList是一個(gè)普通的類,實(shí)現(xiàn)了List接口,具體框架圖如下:

說(shuō)明:

  • ArrayList實(shí)現(xiàn)了RandomAccess接口,表明ArrayList支持隨機(jī)訪問(wèn)
  • 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)類型的順序表

2 ArrayList使用

2.1 ArrayList的構(gòu)造

方法解釋
ArrayList()無(wú)參構(gòu)造
ArrayList(Collection<? extends E> c)利用其他 Collection 構(gòu)建 ArrayList
ArrayList(int initialCapacity)指定順序表初始容量
public static void main(String[] args) {
	// ArrayList創(chuàng)建,推薦寫(xiě)法
	// 構(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)造好之后,與list中的元素一致
	ArrayList<Integer> list3 = new ArrayList<>(list2);
	// 避免省略類型,否則:任意類型的元素都可以存放,使用時(shí)將是一場(chǎng)災(zāi)難
	List list4 = new ArrayList();
	list4.add("111");
	list4.add(100);
}

2.2 ArrayList常見(jiàn)操作

方法解釋
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)刪除遇到的第一個(gè) o
E get(int index)獲取下標(biāo) index 位置元素
E set(int index, E element)將下標(biāo) index 位置元素設(shè)置為 element
void clear()清空
boolean contains(Object o)判斷 o 是否在線性表中
int indexOf(Object o)返回第一個(gè) o 所在下標(biāo)
int lastIndexOf(Object o)返回最后一個(gè) o 的下標(biāo)
List subList(int fromIndex, int toIndex)截取部分 list
public static void main(String[] args) {
	List<String> list = new ArrayList<>();
	list.add("JavaSE");
	list.add("JavaWeb");
	list.add("JavaEE");
	list.add("JVM");
	list.add("測(cè)試課程");
	System.out.println(list);
	// 獲取list中有效元素個(gè)數(shù)
	System.out.println(list.size());
	// 獲取和設(shè)置index位置上的元素,注意index必須介于[0, size)間
	System.out.println(list.get(1));
	list.set(1, "JavaWEB");
	System.out.println(list.get(1));
	// 在list的index位置插入指定元素,index及后續(xù)的元素統(tǒng)一往后搬移一個(gè)位置
	list.add(1, "Java數(shù)據(jù)結(jié)構(gòu)");
	System.out.println(list);
	// 刪除指定元素,找到了就刪除,該元素之后的元素統(tǒng)一往前搬移一個(gè)位置
	list.remove("JVM");
	System.out.println(list);
	// 刪除list中index位置上的元素,注意index不要超過(guò)list中有效元素個(gè)數(shù),否則會(huì)拋出下標(biāo)越界異常
	list.remove(list.size()-1);
	System.out.println(list);

//輸出結(jié)果:
[JavaSE, JavaWeb, JavaEE, JVM, 測(cè)試課程]
5
JavaWeb
JavaWEB
[JavaSE, Java數(shù)據(jù)結(jié)構(gòu), JavaWEB, JavaEE, JVM, 測(cè)試課程]
[JavaSE, Java數(shù)據(jù)結(jié)構(gòu), JavaWEB, JavaEE, 測(cè)試課程]
[JavaSE, Java數(shù)據(jù)結(jié)構(gòu), JavaWEB, JavaEE]

2.3 ArrayList的遍歷

ArrayList 可以使用三方方式遍歷:for循環(huán)+下標(biāo)、foreach、使用迭代器

public static void main(String[] args) {
	List<Integer> list = new ArrayList<>();
	list.add(1);
	list.add(2);
	list.add(3);
	list.add(4);
	list.add(5);
	// 使用下標(biāo)+for遍歷
	for (int i = 0; i < list.size(); i++) {
		System.out.print(list.get(i) + " ");
	} 
	System.out.println();
	// 借助foreach遍歷
	for (Integer integer : list) {
		System.out.print(integer + " ");
	} 
	System.out.println();
	Iterator<Integer> it = list.listIterator();
	while(it.hasNext()){
	System.out.print(it.next() + " ");
	} 
	System.out.println();
}

//輸出結(jié)果:
1 2 3 4 5 
1 2 3 4 5 
1 2 3 4 5 

2.4 ArrayList的擴(kuò)容機(jī)制

ArrayList是一個(gè)動(dòng)態(tài)類型的順序表,即:在插入元素的過(guò)程中會(huì)自動(dòng)擴(kuò)容:以下是ArrayList源碼中擴(kuò)容方式

Object[] elementData; // 存放元素的空間
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {}; // 默認(rèn)空間
private static final int DEFAULT_CAPACITY = 10; // 默認(rèn)容量大小
public boolean add(E e) {
	ensureCapacityInternal(size + 1); // Increments modCount!!
	elementData[size++] = e;
	return true;
}
private void ensureCapacityInternal(int minCapacity) {
	ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
}
private static int calculateCapacity(Object[] elementData, int minCapacity) {
	if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
		return Math.max(DEFAULT_CAPACITY, minCapacity);
	} 
	return minCapacity;
}
private void ensureExplicitCapacity(int minCapacity) {
	modCount++;
	// overflow-conscious code
	if (minCapacity - elementData.length > 0)
		grow(minCapacity);
	}
	private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
	private void grow(int minCapacity) {
	// 獲取舊空間大小
	int oldCapacity = elementData.length;
	// 預(yù)計(jì)按照1.5倍方式擴(kuò)容
	int newCapacity = oldCapacity + (oldCapacity >> 1);
	// 如果用戶需要擴(kuò)容大小 超過(guò) 原空間1.5倍,按照用戶所需大小擴(kuò)容
	if (newCapacity - minCapacity < 0)
	newCapacity = minCapacity;
	// 如果需要擴(kuò)容大小超過(guò)MAX_ARRAY_SIZE,重新計(jì)算容量大小
	if (newCapacity - MAX_ARRAY_SIZE > 0)
	newCapacity = hugeCapacity(minCapacity);
	// 調(diào)用copyOf擴(kuò)容
	elementData = Arrays.copyOf(elementData, newCapacity);
}
private static int hugeCapacity(int minCapacity) {
	// 如果minCapacity小于0,拋出OutOfMemoryError異常
	if (minCapacity < 0)
	throw new OutOfMemoryError();
	return (minCapacity > MAX_ARRAY_SIZE) ? Integer.MAX_VALUE : MAX_ARRAY_SIZE;
}

檢測(cè)是否真正需要擴(kuò)容,如果是調(diào)用grow準(zhǔn)備擴(kuò)容

預(yù)估需要庫(kù)容的大小

  • 初步預(yù)估按照1.5倍大小擴(kuò)容
  • 如果用戶所需大小超過(guò)預(yù)估1.5倍大小,則按照用戶所需大小擴(kuò)容
  • 真正擴(kuò)容之前檢測(cè)是否能擴(kuò)容成功,防止太大導(dǎo)致擴(kuò)容失敗

使用copyOf進(jìn)行擴(kuò)容

3 使用示例

撲克牌:

public class Card {
	public int rank; // 牌面值
	public String suit; // 花色
	@Override
	public String toString() {
		return String.format("[%s %d]", suit, rank);
	}
}
import java.util.List;
import java.util.ArrayList;
import java.util.Random;
public class CardDemo {
	public static final String[] SUITS = {"?", "?", "?", "?"};
	// 買一副牌
	private static List<Card> buyDeck() {
		List<Card> deck = new ArrayList<>(52);
		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();
				card.rank = rank;
				card.suit = suit;
				deck.add(card);
			}
		} 
		return deck;
	}
	private static void swap(List<Card> deck, int i, int j) {
		Card t = deck.get(i);
		deck.set(i, deck.get(j));
		deck.set(j, t);
	}
	private static void shuffle(List<Card> deck) {
		Random random = new Random(20190905);
		for (int i = deck.size() - 1; i > 0; i--) {
			int r = random.nextInt(i);
			swap(deck, i, r);
		}
	}
	public static void main(String[] args) {
		List<Card> deck = buyDeck();
		System.out.println("剛買回來(lái)的牌:");
		System.out.println(deck);
		shuffle(deck);
		System.out.println("洗過(guò)的牌:");
		System.out.println(deck);
		// 三個(gè)人,每個(gè)人輪流抓 5 張牌
		List<List<Card>> hands = new ArrayList<>();
		hands.add(new ArrayList<>());
		hands.add(new ArrayList<>());
		hands.add(new ArrayList<>());
		for (int i = 0; i < 5; i++) {
			for (int j = 0; j < 3; j++) {
				hands.get(j).add(deck.remove(0));
			}
		}
 		System.out.println("剩余的牌:");
		System.out.println(deck);
		System.out.println("A 手中的牌:");
		System.out.println(hands.get(0));
		System.out.println("B 手中的牌:");
		System.out.println(hands.get(1));
		System.out.println("C 手中的牌:");
		System.out.println(hands.get(2));
	}
}

運(yùn)行結(jié)果

剛買回來(lái)的牌:
[[♠ 1], [♠ 2], [♠ 3], [♠ 4], [♠ 5], [♠ 6], [♠ 7], [♠ 8], [♠ 9], [♠ 10], [♠ 11], [♠ 12], [♠ 13], [♥ 1], [♥ 2], [♥ 3], [♥ 4], [♥ 5], [♥ 6], [♥ 7],
[♥ 8], [♥ 9], [♥ 10], [♥ 11], [♥ 12], [♥ 13], [♣ 1], [♣ 2], [♣ 3], [♣ 4], [♣ 5], [♣ 6], [♣ 7], [♣ 8], [♣ 9], [♣ 10], [♣ 11], [♣ 12], [♣
13], [♦ 1], [♦ 2], [♦ 3], [♦ 4], [♦ 5], [♦ 6], [♦ 7], [♦ 8], [♦ 9], [♦ 10], [♦ 11], [♦ 12], [♦ 13]]
洗過(guò)的牌:
[[♥ 11], [♥ 6], [♣ 13], [♣ 10], [♥ 13], [♠ 2], [♦ 1], [♥ 9], [♥ 12], [♦ 5], [♥ 8], [♠ 6], [♠ 3], [♥ 5], [♥ 1], [♦ 6], [♦ 13], [♣ 12], [♦ 12],
[♣ 5], [♠ 4], [♣ 3], [♥ 7], [♦ 3], [♣ 2], [♠ 1], [♦ 2], [♥ 4], [♦ 8], [♠ 10], [♦ 11], [♥ 10], [♦ 7], [♣ 9], [♦ 4], [♣ 8], [♣ 7], [♠ 8], [♦ 9], [♠
12], [♠ 11], [♣ 11], [♦ 10], [♠ 5], [♠ 13], [♠ 9], [♠ 7], [♣ 6], [♣ 4], [♥ 2], [♣ 1], [♥ 3]]
剩余的牌:
[[♦ 6], [♦ 13], [♣ 12], [♦ 12], [♣ 5], [♠ 4], [♣ 3], [♥ 7], [♦ 3], [♣ 2], [♠ 1], [♦ 2], [♥ 4], [♦ 8], [♠ 10], [♦ 11], [♥ 10], [♦ 7], [♣ 9], [♦
4], [♣ 8], [♣ 7], [♠ 8], [♦ 9], [♠ 12], [♠ 11], [♣ 11], [♦ 10], [♠ 5], [♠ 13], [♠ 9], [♠ 7], [♣ 6], [♣ 4], [♥ 2], [♣ 1], [♥ 3]]
A 手中的牌:
[[♥ 11], [♣ 10], [♦ 1], [♦ 5], [♠ 3]]
B 手中的牌:
[[♥ 6], [♥ 13], [♥ 9], [♥ 8], [♥ 5]]
C 手中的牌:
[[♣ 13], [♠ 2], [♥ 12], [♠ 6], [♥ 1]]

到此這篇關(guān)于Java數(shù)據(jù)結(jié)構(gòu)之ArrayList從順序表到實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)Java ArrayList內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • redis在java中的使用(實(shí)例講解)

    redis在java中的使用(實(shí)例講解)

    下面小編就為大家?guī)?lái)一篇redis 在java中的使用(實(shí)例講解)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-08-08
  • Java怎么獲取多網(wǎng)卡本地ip

    Java怎么獲取多網(wǎng)卡本地ip

    java獲取本地ip,獲取多網(wǎng)卡本地ip在項(xiàng)目中經(jīng)常會(huì)用到,下面小編把代碼分享到腳本之家平臺(tái),供大家參考
    2016-03-03
  • Java KindEditor粘貼圖片自動(dòng)上傳到服務(wù)器功能實(shí)現(xiàn)

    Java KindEditor粘貼圖片自動(dòng)上傳到服務(wù)器功能實(shí)現(xiàn)

    這篇文章主要介紹了Java KindEditor粘貼圖片自動(dòng)上傳到服務(wù)器功能實(shí)現(xiàn),本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-04-04
  • SpringBoot攔截器與文件上傳實(shí)現(xiàn)方法與源碼分析

    SpringBoot攔截器與文件上傳實(shí)現(xiàn)方法與源碼分析

    其實(shí)spring boot攔截器的配置方式和springMVC差不多,只有一些小的改變需要注意下就ok了。本文主要給大家介紹了關(guān)于如何在Springboot實(shí)現(xiàn)登陸攔截器與文件上傳功能,需要的朋友可以參考下
    2022-10-10
  • 詳解Java圖形化編程中的鼠標(biāo)事件設(shè)計(jì)

    詳解Java圖形化編程中的鼠標(biāo)事件設(shè)計(jì)

    這篇文章主要介紹了Java圖形化編程中的鼠標(biāo)事件設(shè)計(jì),是Java的GUI開(kāi)發(fā)中的基礎(chǔ)部分,需要的朋友可以參考下
    2015-10-10
  • 利用Java對(duì)比兩個(gè)PDF文件之間的差異

    利用Java對(duì)比兩個(gè)PDF文件之間的差異

    這篇文章主要為大家詳細(xì)介紹了如何在 Java 程序中通過(guò)代碼快速比較兩個(gè) PDF 文檔并找出文檔之間的內(nèi)容差異,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2023-10-10
  • springboot+vue2+elementui實(shí)現(xiàn)時(shí)間段查詢方法

    springboot+vue2+elementui實(shí)現(xiàn)時(shí)間段查詢方法

    這篇文章主要介紹了springboot+vue2+elementui實(shí)現(xiàn)時(shí)間段查詢方法,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),感興趣的朋友跟隨小編一起看看吧
    2024-05-05
  • Java實(shí)現(xiàn)遞歸刪除菜單和目錄及目錄下所有文件

    Java實(shí)現(xiàn)遞歸刪除菜單和目錄及目錄下所有文件

    這篇文章主要為大家詳細(xì)介紹了Java如何實(shí)現(xiàn)遞歸刪除菜單和刪除目錄及目錄下所有文件,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以參考一下
    2025-03-03
  • SpringBoot日志配置SLF4J和Logback的方法實(shí)現(xiàn)

    SpringBoot日志配置SLF4J和Logback的方法實(shí)現(xiàn)

    日志記錄是不可或缺的一部分,本文主要介紹了SpringBoot日志配置SLF4J和Logback的方法實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2025-04-04
  • java匿名內(nèi)部類實(shí)例代碼詳解

    java匿名內(nèi)部類實(shí)例代碼詳解

    這篇文章主要介紹了java匿名內(nèi)部類實(shí)例代碼詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-12-12

最新評(píng)論

枣阳市| 桓仁| 襄城县| 永城市| 平塘县| 南木林县| 理塘县| 丹巴县| 广宁县| 临清市| 安丘市| 慈利县| 平湖市| 宜春市| 高阳县| 阜南县| 香河县| 晋州市| 双城市| 左云县| 区。| 澄江县| 庆阳市| 郧西县| 喜德县| 聂拉木县| 南昌县| 珠海市| 丰原市| 柞水县| 大石桥市| 峨眉山市| 浦城县| 伊吾县| 新巴尔虎右旗| 禹城市| 浮山县| 怀安县| 固镇县| 朝阳县| 汤原县|