深入學習java源碼之AbstractCollection.contains()與AbstractCollection.toArray()
Iterable接口與Iterator接口
Iterator接口
疊代器是一種設計模式,它是一個對象,它可以周遊并選擇序列中的對象,而開發人員不需要了解該序列的底層結構。疊代器通常被稱為“輕量級”對象,因為建立它的代價小。
Java中的Iterator功能比較簡單,并且隻能單向移動:
使用方法iterator()要求容器傳回一個Iterator。第一次調用Iterator的next()方法時,它傳回序列的第一個元素。注意:iterator()方法是java.lang.Iterable接口,被Collection繼承。
實作周遊ArrayList<String>類型。
一開始疊代器在所有元素的左邊,調用next()之後,疊代器移到第一個和第二個元素之間,next()方法傳回疊代器剛剛經過的元素。
hasNext()若傳回True,則表明接下來還有元素,疊代器不在尾部。
remove()方法必須和next方法一起使用,功能是去除剛剛next方法傳回的元素。
Iterator是Java疊代器最簡單的實作,為List設計的ListIterator具有更多的功能,它可以從兩個方向周遊List,也可以從List中插入和删除元素。
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
public class ForEachDemo {
public static void main(String... arg) {
Collection<String> a = new ArrayList<String>();
a.add("Bob");
a.add("Alice");
a.add("Lisy");
Iterator<String> iterator = a.iterator();
while (iterator.hasNext()) {
String ele = iterator.next();
System.out.println(ele);//Bob Alice Lisy
}
System.out.println(a);//[Bob, Alice, Lisy]
iterator = a.iterator();
iterator.next();
iterator.remove();
System.out.println(a);//[Alice, Lisy]
}
}
list l = new ArrayList();
l.add("aa");
l.add("bb");
l.add("cc");
for (Iterator iter = l.iterator(); iter.hasNext();) {
String str = (String)iter.next();
System.out.println(str);
}
/*疊代器用于while循環
Iterator iter = l.iterator();
while(iter.hasNext()){
String str = (String) iter.next();
System.out.println(str);
}
*/
Iterable接口
for-each循環可以與任何實作了Iterable接口的對象一起工作。
而java.util.Collection接口繼承java.lang.Iterable,故标準類庫中的任何集合都可以使用for-each循環。
為什麼一定要去實作Iterable這個接口呢? 為什麼不直接實作Iterator接口呢?
看一下JDK中的集合類,比如List一族或者Set一族,
都是繼承了Iterable接口,但并不直接繼承Iterator接口。
仔細想一下這麼做是有道理的。因為Iterator接口的核心方法next()或者hasNext()
是依賴于疊代器的目前疊代位置的。
如果Collection直接繼承Iterator接口,勢必導緻集合對象中包含目前疊代位置的資料(指針)。
當集合在不同方法間被傳遞時,由于目前疊代位置不可預置,那麼next()方法的結果會變成不可預知。
除非再為Iterator接口添加一個reset()方法,用來重置目前疊代位置。
但即時這樣,Collection也隻能同時存在一個目前疊代位置。
而Iterable則不然,每次調用都會傳回一個從頭開始計數的疊代器。
多個疊代器是互不幹擾的。
class Student {
private String sid;
private String name;
public Student(String sid, String name) {
setSid(sid);
setName(name);
}
public String getSid() {
return sid;
}
public void setSid(String sid) {
this.sid = sid;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Student{" +
"sid='" + sid + '\'' +
", name='" + name + '\'' +
'}';
}
}
支援for each疊代循環的學生集合類
class Students implements Iterable<Student> {
// 存儲所有學生類的數組
private Student[] students;
// 該構造函數可以生成指定大小的學生類變量數組,并初始化該學生類變量數組
public Students(int size) {
students = new Student[size];
for (int i = 0; i < size; i++) {
students[i] = new Student(String.valueOf(i), "學生" + String.valueOf(i));
}
}
@Override
public Iterator<Student> iterator() {
return new StudentIterator();
}
// 實作Iterator接口的私有内部類,外界無法直接通路
private class StudentIterator implements Iterator<Student> {
// 目前疊代元素的下标
private int index = 0;
// 判斷是否還有下一個元素,如果疊代到最後一個元素就傳回false
public boolean hasNext() {
return index != students.length;
}
@Override
public Student next() {
return students[index++];
}
// 這裡不支援,抛出不支援操作異常
public void remove() {
throw new UnsupportedOperationException();
}
}
}
public class ForEachAPIDemo {
public static void main(String[] args) throws Exception {
Students students = new Students(10);
for (Student student : students) {
System.out.println(student.getSid() + ":" + student.getName());
}
}
}
AbstractCollection實作自己的可疊代集合類
Colllection是 java.uitl包中所有集合類的一個根接口.. 是以我們可以通過實作Collection接口來實作自己的集合類..
不過由于Collection接口 方法太多.. 于是JDK提供了AbstractCollection抽象類...
這個類是Collection的一個骨幹..即為我們提供了Collection的大量實作..我們隻需要實作 iterator 和size方法 ...如果我們想要修改自己建立的容器那麼要實作add和remove方法否則 。。
進行修改操作會抛出UnSupporttedException異常 下面是一個例子 ...
在生成疊代器的時候結合局部内部類使用
class Info{
String info=null ;
public Info(String name) {
this.info=name ;
}
@Override
public String toString() {
return this.getClass().getName()+": "+info;
}
}
import java.util.AbstractCollection;
import java.util.Iterator;
class MyCollection extends AbstractCollection<Info>{
private Info []arr =new Info[100];
private int count= 0;
public boolean add(Info info){
if(count<=arr.length){
arr[count++]=info ;
return true ;
}
return false;
}
@Override
public boolean equals(Object obj) {
// TODO Auto-generated method stub
return super.equals(obj);
}
@Override
public Iterator<Info> iterator() {
return new Iterator<Info>() {
private int flag=0 ;
@Override
public boolean hasNext() {
return flag<MyCollection.this.count ;
}
@Override
public Info next() {
return arr[flag++];
}
@Override
public void remove() { //支援删除操作
throw new UnsupportedOperationException() ;
}
};
}
@Override
public int size() {
return 0;
}
}
public class Me {
public static void main(String []agrs){
MyCollection me=new MyCollection() ;
me.add(new Info("zhangsan ")) ;
me.add(new Info("lisi ")) ;
me.add(new Info("zwangwu ")) ;
me.add(new Info("zmaliu ")) ;
for(Info i:me){
System.out.println(i);
}
}
}
java源碼
Modifier and Type | Method and Description |
---|---|
| 確定此集合包含指定的元素(可選操作)。 |
| 将指定集合中的所有元素添加到此集合(可選操作)。 |
| 從此集合中删除所有元素(可選操作)。 |
| 如果此集合包含指定的元素,則傳回 true 。 |
| 如果此集合包含指定 集合中的所有元素,則傳回true。 |
| 如果此集合不包含元素,則傳回 true 。 |
| 傳回包含在該集合中的元素的疊代器。 |
| 從該集合中删除指定元素的單個執行個體(如果存在)(可選操作)。 |
| 删除指定集合中包含的所有此集合的元素(可選操作)。 |
| 僅保留此集合中包含在指定集合中的元素(可選操作)。 |
| 傳回此集合中的元素數。 |
| 傳回一個包含此集合中所有元素的數組。 |
| 傳回包含此集合中所有元素的數組; 傳回的數組的運作時類型是指定數組的運作時類型。 |
| 傳回此集合的字元串表示形式。 |
package java.util;
public abstract class AbstractCollection<E> implements Collection<E> {
protected AbstractCollection() {
}
public abstract Iterator<E> iterator();
public abstract int size();
public boolean isEmpty() {
return size() == 0;
}
public boolean contains(Object o) {
Iterator<E> it = iterator();
if (o==null) {
while (it.hasNext())
if (it.next()==null)
return true;
} else {
while (it.hasNext())
if (o.equals(it.next()))
return true;
}
return false;
}
public Object[] toArray() {
// Estimate size of array; be prepared to see more or fewer elements
Object[] r = new Object[size()];
Iterator<E> it = iterator();
for (int i = 0; i < r.length; i++) {
if (! it.hasNext()) // fewer elements than expected
return Arrays.copyOf(r, i);
r[i] = it.next();
}
return it.hasNext() ? finishToArray(r, it) : r;
}
@SuppressWarnings("unchecked")
public <T> T[] toArray(T[] a) {
// Estimate size of array; be prepared to see more or fewer elements
int size = size();
T[] r = a.length >= size ? a :
(T[])java.lang.reflect.Array
.newInstance(a.getClass().getComponentType(), size);
Iterator<E> it = iterator();
for (int i = 0; i < r.length; i++) {
if (! it.hasNext()) { // fewer elements than expected
if (a == r) {
r[i] = null; // null-terminate
} else if (a.length < i) {
return Arrays.copyOf(r, i);
} else {
System.arraycopy(r, 0, a, 0, i);
if (a.length > i) {
a[i] = null;
}
}
return a;
}
r[i] = (T)it.next();
}
// more elements than expected
return it.hasNext() ? finishToArray(r, it) : r;
}
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
@SuppressWarnings("unchecked")
private static <T> T[] finishToArray(T[] r, Iterator<?> it) {
int i = r.length;
while (it.hasNext()) {
int cap = r.length;
if (i == cap) {
int newCap = cap + (cap >> 1) + 1;
// overflow-conscious code
if (newCap - MAX_ARRAY_SIZE > 0)
newCap = hugeCapacity(cap + 1);
r = Arrays.copyOf(r, newCap);
}
r[i++] = (T)it.next();
}
// trim if overallocated
return (i == r.length) ? r : Arrays.copyOf(r, i);
}
private static int hugeCapacity(int minCapacity) {
if (minCapacity < 0) // overflow
throw new OutOfMemoryError
("Required array size too large");
return (minCapacity > MAX_ARRAY_SIZE) ?
Integer.MAX_VALUE :
MAX_ARRAY_SIZE;
}
public boolean add(E e) {
throw new UnsupportedOperationException();
}
public boolean remove(Object o) {
Iterator<E> it = iterator();
if (o==null) {
while (it.hasNext()) {
if (it.next()==null) {
it.remove();
return true;
}
}
} else {
while (it.hasNext()) {
if (o.equals(it.next())) {
it.remove();
return true;
}
}
}
return false;
}
public boolean containsAll(Collection<?> c) {
for (Object e : c)
if (!contains(e))
return false;
return true;
}
public boolean addAll(Collection<? extends E> c) {
boolean modified = false;
for (E e : c)
if (add(e))
modified = true;
return modified;
}
public boolean removeAll(Collection<?> c) {
Objects.requireNonNull(c);
boolean modified = false;
Iterator<?> it = iterator();
while (it.hasNext()) {
if (c.contains(it.next())) {
it.remove();
modified = true;
}
}
return modified;
}
public boolean retainAll(Collection<?> c) {
Objects.requireNonNull(c);
boolean modified = false;
Iterator<E> it = iterator();
while (it.hasNext()) {
if (!c.contains(it.next())) {
it.remove();
modified = true;
}
}
return modified;
}
public void clear() {
Iterator<E> it = iterator();
while (it.hasNext()) {
it.next();
it.remove();
}
}
public String toString() {
Iterator<E> it = iterator();
if (! it.hasNext())
return "[]";
StringBuilder sb = new StringBuilder();
sb.append('[');
for (;;) {
E e = it.next();
sb.append(e == this ? "(this Collection)" : e);
if (! it.hasNext())
return sb.append(']').toString();
sb.append(',').append(' ');
}
}
}
Modifier and Type | Method and Description |
---|---|
| 確定此集合包含指定的元素(可選操作)。 |
| 将指定集合中的所有元素添加到此集合(可選操作)。 |
| 從此集合中删除所有元素(可選操作)。 |
| 如果此集合包含指定的元素,則傳回 true 。 |
| 如果此集合包含指定 集合中的所有元素,則傳回true。 |
| 将指定的對象與此集合進行比較以獲得相等性。 |
| 傳回此集合的哈希碼值。 |
| 如果此集合不包含元素,則傳回 true 。 |
| 傳回此集合中的元素的疊代器。 |
| 傳回可能并行的 與此集合作為其來源。 |
| 從該集合中删除指定元素的單個執行個體(如果存在)(可選操作)。 |
| 删除指定集合中包含的所有此集合的元素(可選操作)。 |
| 删除滿足給定謂詞的此集合的所有元素。 |
| 僅保留此集合中包含在指定集合中的元素(可選操作)。 |
| 傳回此集合中的元素數。 |
| 建立一個 在這個集合中的元素。 |
| 傳回以此集合作為源的順序 。 |
| 傳回一個包含此集合中所有元素的數組。 |
| 傳回包含此集合中所有元素的數組; 傳回的數組的運作時類型是指定數組的運作時類型。 |
package java.util;
import java.util.function.Predicate;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;
public interface Collection<E> extends Iterable<E> {
int size();
boolean isEmpty();
boolean contains(Object o);
Iterator<E> iterator();
Object[] toArray();
<T> T[] toArray(T[] a);
boolean add(E e);
boolean remove(Object o);
boolean containsAll(Collection<?> c);
boolean addAll(Collection<? extends E> c);
boolean removeAll(Collection<?> c);
default boolean removeIf(Predicate<? super E> filter) {
Objects.requireNonNull(filter);
boolean removed = false;
final Iterator<E> each = iterator();
while (each.hasNext()) {
if (filter.test(each.next())) {
each.remove();
removed = true;
}
}
return removed;
}
boolean retainAll(Collection<?> c);
void clear();
boolean equals(Object o);
int hashCode();
@Override
default Spliterator<E> spliterator() {
return Spliterators.spliterator(this, 0);
}
default Stream<E> stream() {
return StreamSupport.stream(spliterator(), false);
}
default Stream<E> parallelStream() {
return StreamSupport.stream(spliterator(), true);
}
}
實作此接口允許對象成為“for-each loop”語句的目标。
Modifier and Type | Method and Description |
---|---|
| 對 的每個元素執行給定的操作,直到所有元素都被處理或動作引發異常。 |
| 傳回類型為 元素的疊代器。 |
| 在Iterable描述的元素上建立一個 。 |
package java.lang;
import java.util.Iterator;
import java.util.Objects;
import java.util.Spliterator;
import java.util.Spliterators;
import java.util.function.Consumer;
public interface Iterable<T> {
Iterator<T> iterator();
default void forEach(Consumer<? super T> action) {
Objects.requireNonNull(action);
for (T t : this) {
action.accept(t);
}
}
default Spliterator<T> spliterator() {
return Spliterators.spliteratorUnknownSize(iterator(), 0);
}
}
Modifier and Type | Method and Description |
---|---|
| 對每個剩餘元素執行給定的操作,直到所有元素都被處理或動作引發異常。 |
| 如果疊代具有更多元素,則傳回 。 |
| 傳回疊代中的下一個元素。 |
| 從底層集合中删除此疊代器傳回的最後一個元素(可選操作)。 |
package java.util;
import java.util.function.Consumer;
public interface Iterator<E> {
boolean hasNext();
E next();
default void remove() {
throw new UnsupportedOperationException("remove");
}
default void forEachRemaining(Consumer<? super E> action) {
Objects.requireNonNull(action);
while (hasNext())
action.accept(next());
}
}