深入学习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。
boolean
isEmpty()
如果此集合不包含元素,则返回 true 。
abstract Iterator
iterator()
返回包含在该集合中的元素的迭代器。
boolean
remove(Object o)
从该集合中删除指定元素的单个实例(如果存在)(可选操作)。
boolean
removeAll(Collection c)
删除指定集合中包含的所有此集合的元素(可选操作)。
boolean
retainAll(Collection c)
仅保留此集合中包含在指定集合中的元素(可选操作)。
abstract int
size()
返回此集合中的元素数。
Object[]
toArray()
返回一个包含此集合中所有元素的数组。
T[]
toArray(T[] a)
返回包含此集合中所有元素的数组; 返回的数组的运行时类型是指定数组的运行时类型。
String
toString()
返回此集合的字符串表示形式。
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
boolean
add(E e)
确保此集合包含指定的元素(可选操作)。
boolean
addAll(Collection c)
如果此集合包含指定 集合中的所有元素,则返回true。
boolean
equals(Object o)
将指定的对象与此集合进行比较以获得相等性。
int
hashCode()
返回此集合的哈希码值。
boolean
isEmpty()
如果此集合不包含元素,则返回 true 。
Iterator
iterator()
返回此集合中的元素的迭代器。
default Stream
parallelStream()
返回可能并行的
Stream
与此集合作为其来源。boolean
remove(Object o)
从该集合中删除指定元素的单个实例(如果存在)(可选操作)。
boolean
removeAll(Collection c)
删除指定集合中包含的所有此集合的元素(可选操作)。
default boolean
removeIf(Predicate c)
仅保留此集合中包含在指定集合中的元素(可选操作)。
int
size()
返回此集合中的元素数。
default Spliterator
spliterator()
创建一个
Spliterator
在这个集合中的元素。default Stream
stream()
返回以此集合作为源的顺序
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 void
forEach(Consumer
关注打赏
最近更新
- 深拷贝和浅拷贝的区别(重点)
- 【Vue】走进Vue框架世界
- 【云服务器】项目部署—搭建网站—vue电商后台管理系统
- 【React介绍】 一文带你深入React
- 【React】React组件实例的三大属性之state,props,refs(你学废了吗)
- 【脚手架VueCLI】从零开始,创建一个VUE项目
- 【React】深入理解React组件生命周期----图文详解(含代码)
- 【React】DOM的Diffing算法是什么?以及DOM中key的作用----经典面试题
- 【React】1_使用React脚手架创建项目步骤--------详解(含项目结构说明)
- 【React】2_如何使用react脚手架写一个简单的页面?