package java.util;
import java.util.function.Predicate;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;
/**
*1.Collection接口是集合继承关系中的根接口(root interface),有些集合允许重复元素,
* 有些集合有序,JDK不提供本接口的实现,只提供子接口的实现(例如Set,List)
*2.所有实现Collection(或者其子接口)的类都必须包含两个构造函数:无参的构造函数,
* 以及参数为Collection的拷贝构造函数
*
* @author Josh Bloch
* @author Neal Gafter
* @see Set
* @see List
* @see Map
* @see SortedSet
* @see SortedMap
* @see HashSet
* @see TreeSet
* @see ArrayList
* @see LinkedList
* @see Vector
* @see Collections
* @see Arrays
* @see AbstractCollection
* @since 1.2
*/
public interface Collection<E> extends Iterable<E> {
//Query Operations 查询操作
//返回集合中存在的元素数目,如果元素的数目超过Integer.MAX_VALUE,返回Integer.MAX_VALUE
int size();
//当集合不包含任何元素时,返回true
boolean isEmpty();
//如果集合中包含至少一个指定对象,返回true
boolean contains(Object o);
//返回可以遍历集合元素的迭代器
Iterator<E> iterator();
//返回集合中所有元素组成的数组,数组元素的返回顺序要和迭代器访问集合元素的返回顺序一样
Object[] toArray();
//返回包含此 collection 中所有元素的数组;返回数组的运行时类型与指定数组的运行时类型相同。
<T> T[] toArray(T[] a);
//Modification Operations(修改操作)
//如果集合不允许重复元素,且集合中已经含有该元素,返回false
boolean add(E e);
//从此 collection 中移除指定元素的单个实例,如果集合中存在指定元素返回true。
boolean remove(Object o);
// Bulk Operations 批量操作
//如果此 collection 包含指定 collection 中的所有元素,则返回 true。
boolean containsAll(Collection<?> c);
//将指定 collection 中的所有元素都添加到此 collection 中
boolean addAll(Collection<? extends E> c);
//移除此 collection 中那些也包含在指定 collection 中的所有元素(可选操作)。
boolean removeAll(Collection<?> c);
/**
* 移除集合中满足给定条件的所有元素,错误或者运行时异常发生在迭代时或者把条件传递给调用者的时候。
*
* @implSpec
* 默认的实现贯穿了使用迭代器iterator的集合的所有元素。每一个匹配的元素都将被用Iterator接口中的
* remove()方法移除。如果集合的迭代器不支持移除,则在第一次匹配时就会抛出异常 UnsupportedOperationException
*
* @param filter 令元素移除成功的条件
* @return {@code true} 如果所有的元素都被移除
* @throws NullPointerException 如果有这个过滤器是空的
* @throws UnsupportedOperationException 如果元素不能被从该集合中移除。如果一个匹配元素不能被移除,
* 通常来说,它就不支持移除操作,这时可能抛出这个异常。
* @since 1.8
*/
default boolean removeIf(Predicate<? super E> filter) { //Java8在接口中新引入了一种default方法。目的是保留原先的结构,只将改动加入到接口中。
Objects.requireNonNull(filter); //如果有这个过滤器是空则抛出NullPointerException异常
boolean removed = false; //定义的一个判断是否被移除的标志
final Iterator<E> each = iterator(); //final修饰的类,我们只能用,不用继承,被final修饰的变量就是一个常量,只能赋值一次。
while (each.hasNext()) {
if (filter.test(each.next())) { //删除符合过滤器的元素
each.remove();
removed = true;
}
}
return removed;
}
//仅保留此 collection 中那些也包含在指定 collection 的元素(可选操作)
boolean retainAll(Collection<?> c);
//移除此 collection 中的所有元素(可选操作),如果此collection不支持清除操作则抛出UnsupportedOperationException异常。
void clear();
// Comparison and hashing(比较和散列)
/**
* 比较此 collection 与指定对象是否相等。通过覆盖,实现list与list相等,set与set相等
* @see Object#equals(Object)
* @see Set#equals(Object)
* @see List#equals(Object)
*/
boolean equals(Object o);
/**
* @return 返回此 collection 的哈希码值。
*
* @see Object#hashCode()
* @see Object#equals(Object)
*/
int hashCode();
/**
* Creates a {@link Spliterator} over the elements in this collection.
*
* Implementations should document characteristic values reported by the
* spliterator. Such characteristic values are not required to be reported
* if the spliterator reports {@link Spliterator#SIZED} and this collection
* contains no elements.
*
* <p>The default implementation should be overridden by subclasses that
* can return a more efficient spliterator. In order to
* preserve expected laziness behavior for the {@link #stream()} and
* {@link #parallelStream()}} methods, spliterators should either have the
* characteristic of {@code IMMUTABLE} or {@code CONCURRENT}, or be
* <em><a href="Spliterator.html#binding">late-binding</a></em>.
* If none of these is practical, the overriding class should describe the
* spliterator's documented policy of binding and structural interference,
* and should override the {@link #stream()} and {@link #parallelStream()}
* methods to create streams using a {@code Supplier} of the spliterator,
* as in:
* <pre>{@code
* Stream<E> s = StreamSupport.stream(() -> spliterator(), spliteratorCharacteristics)
* }</pre>
* <p>These requirements ensure that streams produced by the
* {@link #stream()} and {@link #parallelStream()} methods will reflect the
* contents of the collection as of initiation of the terminal stream
* operation.
*
* @implSpec
* The default implementation creates a
* <em><a href="Spliterator.html#binding">late-binding</a></em> spliterator
* from the collections's {@code Iterator}. The spliterator inherits the
* <em>fail-fast</em> properties of the collection's iterator.
* <p>
* The created {@code Spliterator} reports {@link Spliterator#SIZED}.
*
* @implNote
* The created {@code Spliterator} additionally reports
* {@link Spliterator#SUBSIZED}.
*
* <p>If a spliterator covers no elements then the reporting of additional
* characteristic values, beyond that of {@code SIZED} and {@code SUBSIZED},
* does not aid clients to control, specialize or simplify computation.
* However, this does enable shared use of an immutable and empty
* spliterator instance (see {@link Spliterators#emptySpliterator()}) for
* empty collections, and enables clients to determine if such a spliterator
* covers no elements.
*
* @return a {@code Spliterator} over the elements in this collection
* @since 1.8
*/
@Override
default Spliterator<E> spliterator() {
return Spliterators.spliterator(this, 0);
}
/**
* Returns a sequential {@code Stream} with this collection as its source.
*
* <p>This method should be overridden when the {@link #spliterator()}
* method cannot return a spliterator that is {@code IMMUTABLE},
* {@code CONCURRENT}, or <em>late-binding</em>. (See {@link #spliterator()}
* for details.)
*
* @implSpec
* The default implementation creates a sequential {@code Stream} from the
* collection's {@code Spliterator}.
*
* @return a sequential {@code Stream} over the elements in this collection
* @since 1.8
*/
default Stream<E> stream() {
return StreamSupport.stream(spliterator(), false);
}
/**
* Returns a possibly parallel {@code Stream} with this collection as its
* source. It is allowable for this method to return a sequential stream.
*
* <p>This method should be overridden when the {@link #spliterator()}
* method cannot return a spliterator that is {@code IMMUTABLE},
* {@code CONCURRENT}, or <em>late-binding</em>. (See {@link #spliterator()}
* for details.)
*
* @implSpec
* The default implementation creates a parallel {@code Stream} from the
* collection's {@code Spliterator}.
*
* @return a possibly parallel {@code Stream} over the elements in this
* collection
* @since 1.8
*/
default Stream<E> parallelStream() {
return StreamSupport.stream(spliterator(), true);
}
}
下面三个方法里面用到了几个JDK8里面才出现的类:Spliterator接口,Spliterators类,StreamSupport类,Stream接口,BaseStream接口。上面还有一个removeIf这个JDK8才出现的方法也用到了Predicate这个接口。我会在下面的分析当中分析完了,再来看看这几个方法。
实际练习代码:
public static void main(String[] args) {
List<Integer> list = new ArrayList<>();
list.add(1);
list.add(2);
list.add(3);
list.add(4);
list.removeIf(s -> s%2==0); // 过滤掉模2等于0的数
list.forEach(s -> System.out.println(s)); // 输出 1 3
List<String> strings = new ArrayList<>();
strings.add("ab");
strings.add("ac");
strings.add("bc");
strings.add("cd");
Predicate<String> predicate = (s) -> s.startsWith("a"); // 这里单独定义了过滤器
strings.removeIf(predicate); // 过滤掉以"a"开头的元素
strings.forEach(s -> System.out.println(s)); // 输出 bc cd
}
参考:https://blog.csdn.net/HelloMrZheng/article/details/70148300