Collection和Iterator接口
Posted everyingo
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Collection和Iterator接口相关的知识,希望对你有一定的参考价值。
Collection接口是List,Set,Queue接口的父接口,该接口里定义的方法既可用于操作Set集合,也可用于操作List和Queue集合。
1.使用Lambda表达式遍历集合
Java8为Iterable接口新增了一个forEach(Consumer action)默认方法,该方法所需参数的类型是一个函数式接口,而Iterable接口是Collection接口的父接口,因此Collection结合也可以直接调用该方法。
当程序调用Iterable的forEach(Consumer action)遍历集合元素时,程序会依次将集合元素传给Consumer的accept(T t)方法,因为Consumer时函数式接口,因此可以使用Lambda表达式来遍历集合元素。
示例代码:
public static void listForEach() {
List<String> list = Arrays.asList(new String[]{"a", "b", "c", "d", "e", "f"});
list.forEach(new Consumer<String>() {
@Override
public void accept(String s) {
System.out.println("str:" + s);
}
});
}
public static void listForEachLambda() {
List<String> list = Arrays.asList(new String[]{"a", "b", "c", "d", "e", "f"});
list.forEach(s -> {
System.out.println("lambda_str:" + s);
});
}
运行结果:
str:a
str:b
str:c
str:d
str:e
str:f
lambda_str:a
lambda_str:b
lambda_str:c
lambda_str:d
lambda_str:e
lambda_str:f
Iterable接口forEach(Consumer<? super T> action)源码:集合内部foreach调用Consumer对象(匿名对象)的accept()方法。
default void forEach(Consumer<? super T> action) {
Objects.requireNonNull(action);
for (T t : this) {
action.accept(t);
}
}
2.使用Java8增强的Iterator遍历集合元素
Iterator接口也是Java集合框架的成员,但是与Collection系系列,Map系列集合不一样:Collection系列集合,Map系列集合主要用于盛装其他对象,而Iterator则主要用于遍历Collection集合中的元素,Iterator对象也被称为迭代器。
iterator 遍历代码:
List<String> list = new ArrayList<>(Arrays.asList(new String[]{"a", "b", "c", "d", "e", "f"}));
Iterator iterator = list.iterator();
while (iterator.hasNext()) {
String str = (String) iterator.next();
if ("c".equals(str)) {
//从集合中删除上一次next()方法返回的元素
iterator.remove();
}
}
//使用Lambda表达式遍历Iterator
list.iterator().forEachRemaining(s -> System.out.println(s));
运行结果:
a
b
d
e
f
remove代码:
List<String> list = new ArrayList<>(Arrays.asList(new String[]{"a", "b", "c", "d", "e", "f"}));
Iterator iterator = list.iterator();
while (iterator.hasNext()) {
String str = (String) iterator.next();
if ("c".equals(str)) {
//使用Iterator迭代过程中,不可修改集合元素,将引发异常:java.util.ConcurrentModificationException
list.remove(str);
}
System.out.println(str);
}
List<String> list = new ArrayList<>(Arrays.asList(new String[]{"a", "b", "c", "d", "e", "f"}));
for (String s : list) {
if ("c".equals(s)) {
// 将引发异常:java.util.ConcurrentModificationException
list.remove(s);
}
}
3.使用Java8新增的Predicate操作集合
Java8为Collection集合新增了一个removeIf(Predicate filter)方法,该方法将会批量删除符合filter条件的所有元素。该方法需要一个Predicate(谓词)对象作为参数,Predicate也是函数式接口,因此也可以使用Lambda表达式作为参数。
示例代码:
public static void listPredicate() {
/**
* 调用Arrays.asList()生产的List的add、remove方法时报异常,这是由Arrays.asList() 返回的市Arrays的内部类ArrayList, 而不是java.util.ArrayList。
* Arrays的内部类ArrayList和java.util.ArrayList都是继承AbstractList,remove、add等方法AbstractList中是默认throw UnsupportedOperationException而且不作任何操作。
* java.util.ArrayList重新了这些方法而Arrays的内部类ArrayList没有重新,所以会抛出异常
*/
List<String> aslist = Arrays.asList(new String[]{"1", "2", "3", "4", "5", "6"});
/**
* 解决方法如下
*/
List<String> list = new ArrayList<>(aslist);
list.removeIf(new Predicate<String>() {
@Override
public boolean test(String s) {
if (s.equals("3")) {
return true;
}
return false;
}
});
list.forEach(s -> System.out.println(s));
}
public static void listPredicateLambda() {
List<String> aslist = Arrays.asList(new String[]{"1", "2", "3", "4", "5", "6"});
List<String> list = new ArrayList<>(aslist);
list.removeIf(s -> (s.equals("3")));
list.forEach(s -> System.out.println(s));
}
运行结果:
1
2
4
5
6
Collection接口removeIf(Predicate<? super E> filter)源码:遍历集合内部元素依据Predicate对象(匿名对象)test()自定义方法体返回值决定是否删除集合中的对象。
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;
}
PredicateDemo:
public static void listPredicateDemo() {
List<String> aslist = Arrays.asList(new String[]{"1", "2", "2", "2", "3", "3"});
System.out.println("1出现的次数:" + totalNumer(aslist, (s -> (s.equals("1")))));
System.out.println("2出现的次数:" + totalNumer(aslist, (s -> (s.equals("2")))));
System.out.println("总数字:" + totalNumer(aslist, (s -> (1 == 1))));
}
private static int totalNumer(Collection collection, Predicate predicate) {
int total = 0;
for (Object o : collection) {
if (predicate.test(o)) {
total++;
}
}
return total;
}
运行结果:
1出现的次数:1
2出现的次数:3
总数字:6
以上是关于Collection和Iterator接口的主要内容,如果未能解决你的问题,请参考以下文章
Java集合框架--Collection接口的使用 & 迭代器(Iterator)遍历原理