深入学习java源码之AbstractCollection.contains()与AbstractCollection.toArray()
Iterable接口与Iterator接口
Iterator接口
迭代器是一种设计模式,它是一个对象,它可以遍历并选择序列中的对象,而开发人员不需要了解该序列的底层结构。迭代器通常被称为“轻量级”对象,因为创建它的代价小。
Java中的Iterator功能比较简单,并且只能单向移动:
使用方法iterator()要求容器返回一个Iterator。第一次调用Iterator的next()方法时,它返回序列的第一个元素。注意:iterator()方法是java.lang.Iterable接口,被Collection继承。
实现遍历ArrayList类型。 一开始迭代器在所有元素的左边,调用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 a = new ArrayList();
a.add("Bob");
a.add("Alice");
a.add("Lisy");
Iterator 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 {
// 存储所有学生类的数组
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 iterator() {
return new StudentIterator();
}
// 实现Iterator接口的私有内部类,外界无法直接访问
private class StudentIterator implements Iterator {
// 当前迭代元素的下标
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{ private Info []arr =new Info[100]; private int count= 0; public boolean add(Info info){ if(count c)如果此集合包含指定 集合中的所有元素,则返回true。
booleanisEmpty()如果此集合不包含元素,则返回 true 。
abstract Iteratoriterator()返回包含在该集合中的元素的迭代器。
booleanremove(Object o)从该集合中删除指定元素的单个实例(如果存在)(可选操作)。
booleanremoveAll(Collection c)删除指定集合中包含的所有此集合的元素(可选操作)。
booleanretainAll(Collection c)仅保留此集合中包含在指定集合中的元素(可选操作)。
abstract intsize()返回此集合中的元素数。
Object[]toArray()返回一个包含此集合中所有元素的数组。
T[]toArray(T[] a)返回包含此集合中所有元素的数组; 返回的数组的运行时类型是指定数组的运行时类型。
StringtoString()返回此集合的字符串表示形式。
package java.util; public abstract class AbstractCollection implements Collection { protected AbstractCollection() { } public abstract Iterator iterator(); public abstract int size(); public boolean isEmpty() { return size() == 0; } public boolean contains(Object o) { Iterator 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 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[] 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 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[] 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 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 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 it = iterator(); while (it.hasNext()) { if (!c.contains(it.next())) { it.remove(); modified = true; } } return modified; } public void clear() { Iterator it = iterator(); while (it.hasNext()) { it.next(); it.remove(); } } public String toString() { Iterator 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 TypeMethod and Description
booleanadd(E e)确保此集合包含指定的元素(可选操作)。
booleanaddAll(Collection c)如果此集合包含指定 集合中的所有元素,则返回true。
booleanequals(Object o)将指定的对象与此集合进行比较以获得相等性。
inthashCode()返回此集合的哈希码值。
booleanisEmpty()如果此集合不包含元素,则返回 true 。
Iteratoriterator()返回此集合中的元素的迭代器。
default StreamparallelStream()返回可能并行的
Stream与此集合作为其来源。booleanremove(Object o)从该集合中删除指定元素的单个实例(如果存在)(可选操作)。
booleanremoveAll(Collection c)删除指定集合中包含的所有此集合的元素(可选操作)。
default booleanremoveIf(Predicate c)仅保留此集合中包含在指定集合中的元素(可选操作)。
intsize()返回此集合中的元素数。
default Spliteratorspliterator()创建一个
Spliterator在这个集合中的元素。default Streamstream()返回以此集合作为源的顺序
Stream。Object[]toArray()返回一个包含此集合中所有元素的数组。
T[]toArray(T[] a)返回包含此集合中所有元素的数组; 返回的数组的运行时类型是指定数组的运行时类型。
package java.util; import java.util.function.Predicate; import java.util.stream.Stream; import java.util.stream.StreamSupport; public interface Collection extends Iterable { int size(); boolean isEmpty(); boolean contains(Object o); Iterator iterator(); Object[] toArray(); T[] toArray(T[] a); boolean add(E e); boolean remove(Object o); boolean containsAll(Collection c); boolean addAll(Collection c); default boolean removeIf(Predicate c); void clear(); boolean equals(Object o); int hashCode(); @Override default Spliterator spliterator() { return Spliterators.spliterator(this, 0); } default Stream stream() { return StreamSupport.stream(spliterator(), false); } default Stream parallelStream() { return StreamSupport.stream(spliterator(), true); } }实现此接口允许对象成为“for-each loop”语句的目标。
Modifier and TypeMethod and Descriptiondefault voidforEach(Consumer关注打赏
