您好,登錄后才能下訂單哦!
今天小編給大家分享一下Java List接口的內容有哪些及如何使用的相關知識點,內容詳細,邏輯清晰,相信大部分人都還太了解這方面的知識,所以分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后有所收獲,下面我們一起來了解一下吧。
List接口是Collection接口的三大接口之一,其中的數據可以通過位置檢索,用戶可以在指定位置插入數據。List的數據可以為空,可以重復。
我們這里就只關注和Collection不同的方法,主要有以下這些:
//在指定位置,將指定的集合插入到當前的集合中
boolean addAll(int index, Collection<? extends E> c);
//這是一個默認實現的方法,會通過Iterator的方式對每個元素進行指定的操作
default void replaceAll(UnaryOperator<E> operator) {
Objects.requireNonNull(operator);
final ListIterator<E> li = this.listIterator();
while (li.hasNext()) {
li.set(operator.apply(li.next()));
}
}
//排序,依據指定的規則對當前集合進行排序,可以看到,排序是通過Arrays這個工具類完成的。
default void sort(Comparator<? super E> c) {
Object[] a = this.toArray();
Arrays.sort(a, (Comparator) c);
ListIterator<E> i = this.listIterator();
for (Object e : a) {
i.next();
i.set((E) e);
}
}
//獲取指定位置的元素
E get(int index);
//修改指定位置元素的值
E set(int index, E element);
//將指定元素添加到指定的位置
void add(int index, E element);
//將指定位置的元素移除
E remove(int index);
//返回一個元素在集合中首次出現的位置
int indexOf(Object o);
//返回一個元素在集合中最后一次出現的位置
int lastIndexOf(Object o);
//ListIterator繼承于Iterator,主要增加了向前遍歷的功能
ListIterator<E> listIterator();
//從指定位置開始,返回一個ListIterator
ListIterator<E> listIterator(int index);
//返回一個子集合[fromIndex, toIndex),非結構性的修改返回值會反映到原表,反之亦然。
//如果原表進行了結構修改,則返回的子列表可能發生不可預料的事情
List<E> subList(int fromIndex, int toIndex);
通過對上面方法的研究,我們不難發現,collection接口主要提供一些通常的方法,而List接口則針對線性表的結構,提供了對位置以及字表的操作。
我們先看看源文檔是怎么來說AbstractList的,要實現一個不可修改的集合,只需要復寫get和size方法。如果要實現一個可以修改的集合,還需要復寫set方法,如果要動態調整大小,就必須實現add和remove方法。
接下里我們一起來來看看源碼吧!
//在AbstractCollection中,add方法默認會拋出異常,
//而在這里是調用了add(int index, E e)方法,但這個方法也是沒有實現的。
//這里默認會把元素添加到末尾。
public boolean add(E e) {
add(size(), e);
return true;
}
//同上,這個只需要進行一次遍歷即可
public boolean addAll(int index, Collection<? extends E> c) {
//...
}
接下里我們在繼續看看其他幾個方法,這幾個是與Iterator和ListIterator息息相關的,在AbstractList中有具體的實現,我們先來看看它是如何把集合轉變成Iterator對象并支持foreach循環的吧。
我們通過源碼發現:在Iterator方法中,是直接返回一個 Itr對象
public Iterator<E> iterator() {
return new Itr();
}
其實我們很快也就會明白,它是實現了一個內部類,這個內部類實現了Iterator接口,合理的處理hasNext、next、remove方法。這個源碼就不粘貼啦,其中僅僅在remove時考慮了一下多線程問題,有興趣的可以自己去看看。
我們來看看另一個吧–ListIterator吧他也是通過一個內部類是實現的
public ListIterator<E> listIterator() {
return listIterator(0);
}
public ListIterator<E> listIterator(final int index) {
rangeCheckForAdd(index);
return new ListItr(index);
}
事實證明,和我們想的一樣,AbstractList內部還定義了一個ListItr,實現了ListIterator接口,其實現也很簡單,就不粘貼源碼啦。
接下倆讓我們來看看AbtractList是怎么利用這兩個類來做事情的
//尋找一個元素首次出現的位置,只需要從前往后遍歷,找到那個元素并返回其位置即可。
public int indexOf(Object o) {
ListIterator<E> it = listIterator();
if (o==null) {
while (it.hasNext())
if (it.next()==null)
return it.previousIndex();
} else {
while (it.hasNext())
if (o.equals(it.next()))
return it.previousIndex();
}
return -1;
}
//同理,尋找一個元素最后一次出現的位置,只需要從列表最后一位向前遍歷即可。
//看到listIterator(int index)方法是可以傳遞參數的,這個我想我們都可以照著寫出來了。
public int lastIndexOf(Object o) {
//...
}
//這個方法是把從fromIndex到toIndex之間的元素從集合中刪除。
//clear()方法也是調用這個實現的(我認為clear實現意義并不大,因為在其上級AbstractCollection中已經有了具體實現)。
protected void removeRange(int fromIndex, int toIndex) {
ListIterator<E> it = listIterator(fromIndex);
for (int i=0, n=toIndex-fromIndex; i<n; i++) {
it.next();
it.remove();
}
}
在接下來讓我們來說一說兩個比較重要的內容一個是關于SubList,另一個是關于equals和hascode的。
SubList并不是新建了一個list,只是持有當前集合的引用,然后控制了用戶可以操作的范圍,所以在接口定義時就說明了其更改會直接反應到原集合中。SubList是定AbstractList內部,并且是AbstractList的基礎上增加了對可選范圍的控制。
而equals和hascode的實現,也關乎我們的使用。在AbstractList中,這兩個方法不僅與其實例有關,也和其內部包含的元素有關,所以在定義數據元素時,也應該復寫這兩個方法,以保證程序的正確運行。這里看下其源碼加深一下印象吧。
public boolean equals(Object o) {
if (o == this)
return true;
if (!(o instanceof List))
return false;
ListIterator<E> e1 = listIterator();
ListIterator<?> e2 = ((List<?>) o).listIterator();
while (e1.hasNext() && e2.hasNext()) {
E o1 = e1.next();
Object o2 = e2.next();
//這里用到了數據元素的equals方法
if (!(o1==null ? o2==null : o1.equals(o2)))
return false;
}
return !(e1.hasNext() || e2.hasNext());
}
public int hashCode() {
int hashCode = 1;
for (E e : this)
//這里用到了數據元素的hashCode方法
hashCode = 31*hashCode + (e==null ? 0 : e.hashCode());
return hashCode;
}
以上就是“Java List接口的內容有哪些及如何使用”這篇文章的所有內容,感謝各位的閱讀!相信大家閱讀完這篇文章都有很大的收獲,小編每天都會為大家更新不同的知識,如果還想學習更多的知識,請關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。