Interable接口新增了一个forEach(Consumer action)默认方法,该方法所需参数的类型是一个函数式接口,而Iterable接口是Collection接口的父接口,因此Collection可以直接调用该方法
程序调用Iterable的forEach(Consumer action)遍历集合元素时,程序会依次将集合元素传给Consumer的accept(T t)方法,因为Consumer是函数式接口,因此可以使用Lambda表达式来遍历集合元素
package demo;
import java.util.*;
import static java.lang.System.*;public class CollectionEach
{public static void main(String[] args){// 创建一个集合HashSet books;books = new HashSet();books.add("天苍苍野茫茫");books.add("风吹草地见牛羊");books.add("我欲乘风归去");books.add("又恐琼楼玉宇");// 调用forEach()方法遍历集合books.forEach(obj -> out.println("迭代集合元素:" + obj));}
}
Collection、Map系列用于装其他对象,而Iterator则主要用于遍历(即迭代访问)Collection集合中的元素,它也被称为迭代器
Iterator接口定义了如下4个方法:
package demo;
import java.util.*;
import static java.lang.System.out;public class IteratorTest
{public static void main(String[] args){// 创建集合、添加元素的代码与前一个程序相同var books = new HashSet();books.add("What are you doing?");books.add("How are you doing today!");books.add("I do not even know what are you doing!");// 获取books集合对应的迭代器var it = books.iterator();while (it.hasNext()){// it.next()方法返回的数据类型是Object类型,因此需要强制类型转换var book = (String) it.next();out.println(book);if (book.equals("How are you doing today!")){// 从集合中删除上一次next方法返回的元素it.remove();}// 对book变量赋值,不会改变集合元素本身book = "测试字符串";}out.println(books);}
}
Iterator必须依附于Collection对象,若有一个Iterator对象则必然有一个与之关联的Collection对象
book = “测试字符串”;虽然进行了赋值,但当在此输出集合的时候没有任何改变,也就是说当使用Iterator对集合元素进行迭代的时候,Iterator并不是把集合元素本身传递给了迭代变量,而是把集合元素的值传递给了迭代变量,所以修改迭代变量的值对集合元素没有任何影响。
package demo;
import java.util.*;
import static java.lang.System.out;public class IteratorErrorTest
{public static void main(String[] args){// 创建集合、添加元素的代码与前一个程序相同var books = new HashSet();books.add("what are you doing now?");books.add("How are you doing today!");books.add("I do not event know what are you doing!");// 获取books集合对应的迭代器var it = books.iterator();while (it.hasNext()){var book = (String) it.next();out.println(book);if (book.equals("How are you doing today!")){// 使用Iterator迭代过程中,不可修改集合元素,下面代码引发异常ve(book);}}}
}
当使用Iterator循环迭代访问集合元素时,集合不能被改变,因此ve(book);会抛异常,只有通过Iterator的remove()方法删除上一次next()方法返回的集合元素才可以。
Java8为Iterator新增了一个forEachRemaining(Consumer action)方法,该方法所需的Consumer参数也是函数式接口
package demo;
import java.util.*;
import static java.lang.System.out;
public class IteratorEach
{public static void main(String[] args){// 创建集合、添加元素的代码与前一个程序相同var books = new HashSet();books.add("What are you donig?");books.add("How are you doing today!");books.add("How are you!");// 获取books集合对应的迭代器var it = books.iterator();// 使用Lambda表达式(目标类型是Comsumer)来遍历集合元素it.forEachRemaining(obj -> out.println("迭代集合元素:" + obj));}
}
package demo;
import java.util.*;
import static java.lang.System.*;public class ForeachTest
{public static void main(String[] args){// 创建集合、添加元素的代码与前一个程序相同var books = new HashSet();books.add(new String("粒粒皆辛苦"));books.add(new String("汗滴禾下土"));books.add(new String("锄禾日当午"));for (var obj : books){// 此处的book变量也不是集合元素本身var book = (String) obj;out.println(book);if (book.equals("我醉欲眠卿且去")){// 下面代码会引发ConcurrentModificationException异常ve(book);}}out.println(books);}
}
当使用foreach循环迭代访问集合元素时,集合不能被改变,因此ve(book);会抛异常
Java8为Collection集合新增了一个removeIf(Predicate filter)方法,该方法将删除符合filter条件的所有元素,而Predicate也是函数式接口,因此可以使用lambda表达式坐位参数
package demo;
import java.util.*;
import java.util.function.*;
import static java.lang.System.out;public class PredicateTest
{public static void main(String[] args) {// 创建一个集合var books = new HashSet();books.add("锄禾日当午锄禾日当午");books.add("汗滴禾下土汗滴禾下土");books.add("谁知盘中餐谁知盘中餐");books.add("粒粒皆辛苦粒粒皆辛苦");books.add("胡说带八道");// 使用Lambda表达式(目标类型是Predicate)过滤集合veIf(ele -> ((String) ele).length() < 10);out.println(books);// 统计书名包含“疯狂”子串的图书数量out.println(calAll(books, ele -> ((String) ele).contains("锄禾")));// 统计书名包含“Java”子串的图书数量out.println(calAll(books, ele -> ((String) ele).contains("盘中餐")));// 统计书名字符串长度大于10的图书数量out.println(calAll(books, ele -> ((String) ele).length() > 10));}public static int calAll(Collection books, Predicate p){int total = 0;for (var obj : books){// 使用Predicate的test()方法判断该对象是否满足Predicate指定的条件if (p.test(obj)){total++;}}return total;}
}
长度小于10的字符串元素都会被删除。
package demo;
import java.util.stream.*;
import static java.lang.System.out;public class IntStreamTest
{public static void main(String[] args){var is = IntStream.builder().add(20).add(13).add(-2).add(18).build();// 下面调用聚集方法的代码每次只能执行一个out.println("is所有元素的最大值:" + is.max().getAsInt());out.println("is所有元素的最小值:" + is.min().getAsInt());out.println("is所有元素的总和:" + is.sum());out.println("is所有元素的总数:" + is.count());out.println("is所有元素的平均值:" + is.average());out.println("is所有元素的平方是否都大于20:" + is.allMatch(ele -> ele * ele > 20));out.println("is是否包含任何元素的平方大于20:" + is.anyMatch(ele -> ele * ele > 20));// 将is映射成一个新Stream,新Stream的每个元素是原Stream元素的2倍+1var newIs = is.map(ele -> ele * 2 + 1);// 使用方法引用的方式来遍历集合元素// 输出41 27 -3 37newIs.forEach(out::println);}
}
Stream提供了大量方法进行聚集操作,有些方法是“中间方法”(intermediate),有些是“末端方法”(teminal)
流的方法还有两个特征
Stream常用的中间方法:
Stream常用的末端方法:
Java8之后允许使用流式API来操作集合,Collection接口提供了一个stream()默认方法,用于返回该集合对应的流
package demo;
import java.util.*;
import static java.lang.System.out;public class CollectionStream
{public static void main(String[] args){// 创建books集合、为books集合添加元素的代码与8.2.5小节的程序相同。var books = new HashSet();books.add("What are you doing now?");books.add("How are you doing today day day?");books.add("How do you do!");books.add("How do you do do do do!");books.add("How are you doing today?");// 统计书名包含“疯狂”子串的图书数量// 输出4out.println(books.stream().filter(ele->((String) ele).contains("疯狂")).count());// 统计书名包含“Java”子串的图书数量// 输出2out.println(books.stream().filter(ele->((String) ele).contains("Java") ).count());// 统计书名字符串长度大于10的图书数量// 输出2out.println(books.stream().filter(ele->((String) ele).length() > 10).count());// 先调用Collection对象的stream()方法将集合转换为Stream对象,// 再调用Stream的mapToInt()方法获取原有的Stream对应的IntStream// 这个mapToInt()就是个中间方法,因此程序可以继续调用forEach()方法遍历IntStream中每个元素// 输出8 11 16 7 8books.stream().mapToInt(ele -> ((String) ele).length()).forEach(out::println);}
}
本文发布于:2024-02-04 23:26:39,感谢您对本站的认可!
本文链接:https://www.4u4v.net/it/170718800960726.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
留言与评论(共有 0 条评论) |