Java面向对象系列[v1.0.1][集合]

阅读: 评论:0

Java面向对象系列[v1.0.1][集合]

Java面向对象系列[v1.0.1][集合]

Lambda表达式遍历集合

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));}
}

Iterator遍历集合元素

Collection、Map系列用于装其他对象,而Iterator则主要用于遍历(即迭代访问)Collection集合中的元素,它也被称为迭代器
Iterator接口定义了如下4个方法:

  • boolean hasNext():如果被迭代的集合元素还没有被遍历完,则返回true
  • Object next():返回集合里下一个元素
  • void remove():删除集合里上一次next方法返回的元素
  • void forEachRemaining(Consumer action):使用Lambda表达式来遍历集合元素
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()方法返回的集合元素才可以。

Lambda表达式遍历Iterator

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));}
}

foreach循环遍历集合元素

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);会抛异常

Predicate操作集合

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的字符串元素都会被删除。

Stream操作集合

  • Java8增加了Stream、IntStream、LongStream和DoubleStream等流式API,这些API代表多个支持串行和并行聚集操作的元素,其中Stream是个通用的流接口,而IntStream、LongStream和DoubleStream代表元素类型为int、long、double的流
  • Java8还为每个流式API提供了对应的Builder,例如Stream.Builder、IntStream.Builder、LongStream.Builder、DoubleStream.Builder,可以通过这些Builder来创建对应的流
  • 当使用Stream的时候,首先是使用对应的builder()类方法创建该Stream对应的Builder,然后重复调用Builder的add()方法向该流中添加多个元素,调用Builder的build()方法获取对应的Stream,调用Stream的聚集方法。
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)

  • 中间方法:中间操作允许流保持打开状态,并允许直接调用后续方法,例如代码中的map()方法就是,中间方法的返回值是另外一个流
  • 末端方法:末端方法是对流的最终操作,当对某个Stream执行末端方法后,该流将会被“消耗”且不再可用,例如代码中的sum()、count()、average()等方法都是末端方法

流的方法还有两个特征

  • 有状态的方法:这种方法会给流增加一些新的属性,比如元素的唯一性、元素的最大数量、保证元素以排序的方式被处理等,但性能开销ye’bi’jiao’da
  • 短路方法:该方法可以尽早结束对流的操作,不必检查所有的元素

Stream常用的中间方法:

  • filter(Predicate predicate):过滤Stream中所有不符合predicate的元素
  • mapToXxx(ToXxxFunction mapper):使用ToXxxFunction对流中的元素执行一对一的转换,该方法返回的新流中包含了ToXxxFunction转换生成的所有元素
  • peek(Consumer action):依次对每个元素执行一些操作,该方法返回的流与原有流包含相同的元素,该方法主要用于调试。
  • distinct():该方法用于排序流中所有重复的元素(判断元素重复的标准是使用equals()比较返回true),这是一个有状态的方法
  • sorted():该方法用于保证流中的元素在后续的访问中处于有序状态,这也是一个有状态的方法
  • limit(long maxSize):该方法用于保证对该流的后续访问中最大允许访问的元素个数,这也是一个有状态的且短路方法

Stream常用的末端方法:

  • forEach(Consumer action): 遍历流中所有元素,对每个元素执行action
  • toArray():将流中所有元素转换为一个数组
  • reduce():该方法有三个重载的版本,都用于通过某种操作来合并流中的元素
  • min():返回流中所有元素的最小值
  • max():返回流中所有元素的最大值
  • count():返回流中所有元素的数量
  • anyMatch(Predicate predicate): 判断流中是否至少包含一个元素符合Predicate条件
  • allMatch(Predicate predicate):判断流中是否每个元素都符合Predicate条件
  • nonMatch(Predicate predicate):判断流中是否所有元素都不符合Predicate条件
  • findFirst():返回流中的第一个元素
  • findAny():返回流中的任意一个元素

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小时内删除。

标签:面向对象   系列   Java
留言与评论(共有 0 条评论)
   
验证码:

Copyright ©2019-2022 Comsenz Inc.Powered by ©

网站地图1 网站地图2 网站地图3 网站地图4 网站地图5 网站地图6 网站地图7 网站地图8 网站地图9 网站地图10 网站地图11 网站地图12 网站地图13 网站地图14 网站地图15 网站地图16 网站地图17 网站地图18 网站地图19 网站地图20 网站地图21 网站地图22/a> 网站地图23