台州哪里做网站,网络营销的十种方法,保险公司十大排名,设计网站 知乎这篇文章介绍了JDK 8的应用–引入了带有集合的 流 #xff0c;以更简洁地完成通常需要的与集合相关的功能。 在此过程中#xff0c;将演示并简要说明使用Java Streams的几个关键方面。 请注意#xff0c;尽管JDK 8 Streams通过并行化支持提供了潜在的性能优势#xff0c;但… 这篇文章介绍了JDK 8的应用–引入了带有集合的 流 以更简洁地完成通常需要的与集合相关的功能。 在此过程中将演示并简要说明使用Java Streams的几个关键方面。 请注意尽管JDK 8 Streams通过并行化支持提供了潜在的性能优势但这并不是本文的重点。 样品采集和采集条目 就本文而言 Movie实例将存储在一个集合中。 以下代码段适用于这些示例中使用的简单Movie类。 电影.java package dustin.examples.jdk8.streams;import java.util.Objects;/*** Basic characteristics of a motion picture.* * author Dustin*/
public class Movie
{/** Title of movie. */private String title;/** Year of movies release. */private int yearReleased;/** Movie genre. */private Genre genre;/** MPAA Rating. */private MpaaRating mpaaRating;/** imdb.com Rating. */private int imdbTopRating;public Movie(final String newTitle, final int newYearReleased,final Genre newGenre, final MpaaRating newMpaaRating,final int newImdbTopRating){this.title newTitle;this.yearReleased newYearReleased;this.genre newGenre;this.mpaaRating newMpaaRating;this.imdbTopRating newImdbTopRating;}public String getTitle(){return this.title;}public int getYearReleased(){return this.yearReleased;}public Genre getGenre(){return this.genre;}public MpaaRating getMpaaRating(){return this.mpaaRating;}public int getImdbTopRating(){return this.imdbTopRating;}Overridepublic boolean equals(Object other){if (!(other instanceof Movie)){return false;}final Movie otherMovie (Movie) other;return Objects.equals(this.title, otherMovie.title) Objects.equals(this.yearReleased, otherMovie.yearReleased) Objects.equals(this.genre, otherMovie.genre) Objects.equals(this.mpaaRating, otherMovie.mpaaRating) Objects.equals(this.imdbTopRating, otherMovie.imdbTopRating);}Overridepublic int hashCode(){return Objects.hash(this.title, this.yearReleased, this.genre, this.mpaaRating, this.imdbTopRating);}Overridepublic String toString(){return Movie: this.title ( this.yearReleased ), this.genre , this.mpaaRating , this.imdbTopRating;}
} Movie多个实例放置在Java Set中 。 下面显示了执行此操作的代码因为它还显示了在这些实例中设置的值。 此代码在类上将“电影”声明为静态字段然后使用静态初始化块用五个Movie实例填充该字段。 用电影类实例填充电影集 private static final SetMovie movies;static
{final SetMovie tempMovies new HashSet();tempMovies.add(new Movie(Raiders of the Lost Ark, 1981, Genre.ACTION, MpaaRating.PG, 31));tempMovies.add(new Movie(Star Wars: Episode V - The Empire Strikes Back, 1980, Genre.SCIENCE_FICTION, MpaaRating.PG, 12));tempMovies.add(new Movie(Inception, 2010, Genre.SCIENCE_FICTION, MpaaRating.PG13, 13));tempMovies.add(new Movie(Back to the Future, 1985, Genre.SCIENCE_FICTION, MpaaRating.PG, 49));tempMovies.add(new Movie(The Shawshank Redemption, 1994, Genre.DRAMA, MpaaRating.R, 1));movies Collections.unmodifiableSet(tempMovies);
}初探带有过滤的JDK 8流 通常在集合上执行的一种功能是过滤。 下一个代码清单显示了如何过滤所有评级为PG的电影的“电影” Set 。 列出之后我将重点介绍可以从此代码中得出的一些观察结果。 使用PG分级过滤电影 /*** Demonstrate using .filter() on Movies stream to filter by PG ratings* and collect() as a Set.*/
private void demonstrateFilteringByRating()
{printHeader(Filter PG Movies);final SetMovie pgMovies movies.stream().filter(movie movie.getMpaaRating() MpaaRating.PG).collect(Collectors.toSet());out.println(pgMovies);
} 第一个示例包括本文中的所有示例也将具有的一件事是在集合上调用方法stream 。 此方法返回一个实现java.util.Stream接口的对象。 这些返回的每个Streams均使用针对其调用stream()方法的集合作为其数据源。 此时所有操作都在Stream上而不是在集合上后者是Stream的数据源。 在上面的代码清单中基于“ movies” Set在Stream上调用filter Predicate 方法。 在这种情况下 Predicate由lambda表达式 movie - movie.getMpaaRating() MpaaRating.PG 。 这种相当可读的表示法告诉我们谓词是基础数据中具有MPAA等级PG的每部电影。 Stream.filterPredicate方法是一个中间操作 这意味着它返回Stream的实例该实例可以由其他操作进一步操作。 在这种情况下还有另一个操作collectCollector 它是由Stream.filter(Predicate)返回的Stream调用的。 Collectors类具有许多静态方法每个方法都提供一个Collector的实现可以将其提供给此collect(Collector)方法。 在这种情况下使用Collectors.toSet获得一个Collector 它将指示将流结果安排在Set 。 Stream.collect(Collector)方法是一个终端操作 这意味着它是该行的结尾并且不返回Stream实例因此在执行此collection之后无法再执行任何Stream操作。 执行上述代码后它将生成如下输出 Filter PG Movies[Movie: Raiders of the Lost Ark (1981), ACTION, PG, 31, Movie: Back to the Future (1985), SCIENCE_FICTION, PG, 49, Movie: Star Wars: Episode V - The Empire Strikes Back (1980), SCIENCE_FICTION, PG, 12]过滤单个第一个结果 /** * Demonstrate using .filter() on Movies stream to filter by #1 imdb.com* rating and using .findFirst() to get first (presumably only) match.*/
private void demonstrateSingleResultImdbRating()
{printHeader(Display One and Only #1 IMDB Movie);final OptionalMovie topMovie movies.stream().filter(movie - movie.getImdbTopRating() 1).findFirst();out.println(topMovie.isPresent() ? topMovie.get() : none);
} 这个例子与前面的例子有很多相似之处。 像之前的代码清单一样该清单显示了Stream.filter(Predicate)的Stream.filter(Predicate) 但是这次谓词是lambda表达式movie - movie.getImdbTopRating() 1) 。 换句话说由此过滤器生成的Stream应该仅包含具有方法getImdbTopRating()返回数字1的Movie实例。然后对Stream.filter(Predicate)返回的Stream执行终止操作Stream.findFirst Stream.filter(Predicate) 。 这将返回流中遇到的第一个条目并且由于我们的基础Movie Set实例只有一个IMDb Top 250 Rating为1的实例因此它将是流中由过滤器生成的第一个也是唯一的条目。 执行此代码清单后其输出如下所示 Display One and Only #1 IMDB MovieMovie: The Shawshank Redemption (1994), DRAMA, R, 1 下一个代码清单说明了Stream.mapFunction的用法 。 /*** Demonstrate using .map to get only specified attribute from each* element of collection.*/
private void demonstrateMapOnGetTitleFunction()
{printHeader(Just the Movie Titles, Please);final ListString titles movies.stream().map(Movie::getTitle).collect(Collectors.toList());out.println(titles.size() titles (in titles.getClass() ): titles);
} 该Stream.map(Function)方法作用于Stream对调用它在我们的例子中 Stream可基于底层Set的Movie对象并应用所提供的功能针对Steam返回一个新的Stream 从结果该Function对源Stream 。 在这种情况下 Function由Movie::getTitle表示这是JDK 8引入的方法reference的示例。 我可以使用lambda表达式movie - movie.getTitle()代替方法参考Movie::getTitle来获得相同的结果。 方法参考文档解释说这正是方法参考旨在解决的情况 您使用lambda表达式创建匿名方法。 但是有时lambda表达式除了调用现有方法外什么也不做。 在这种情况下通常更容易按名称引用现有方法。 方法引用使您可以执行此操作 它们是紧凑的易于阅读的lambda表达式用于已经具有名称的方法。 从上面的代码中您可能会猜到它 Stream.map(Function)是一个中间操作。 就像前面两个示例一样此代码清单应用了Stream.collect(Collector)的终止操作但是在这种情况下是传递给它的是Collectors.toList 因此结果数据结构是List而不是Set 。 当上面的代码清单运行时其输出如下所示 Just the Movie Titles, Please5 titles (in class java.util.ArrayList): [Inception, The Shawshank Redemption, Raiders of the Lost Ark, Back to the Future, Star Wars: Episode V - The Empire Strikes Back] 减少转换为单布尔操作anyMatch和allMatch 下一个示例不使用在大多数先前示例中使用的Stream.filter(Predicate) Stream.map(Function)甚至终止操作Stream.collect(Collector) 。 在此示例中基于我们的Movie对象Set 缩减和终止操作Stream.allMatchPredicate和Stream.anyMatchPredicate直接应用于Stream 。 /*** Demonstrate .anyMatch and .allMatch on stream.*/
private void demonstrateAnyMatchAndAllMatchReductions()
{printHeader(anyMatch and allMatch);out.println(All movies in IMDB Top 250? movies.stream().allMatch(movie - movie.getImdbTopRating() 250));out.println(All movies rated PG? movies.stream().allMatch(movie - movie.getMpaaRating() MpaaRating.PG));out.println(Any movies rated PG? movies.stream().anyMatch(movie - movie.getMpaaRating() MpaaRating.PG));out.println(Any movies not rated? movies.stream().anyMatch(movie - movie.getMpaaRating() MpaaRating.NA));
} 代码清单显示Stream.anyMatch(Predicate)和Stream.allMatch(Predicate)各自返回一个布尔值分别表示其名称是否暗示Stream具有至少一个与谓词匹配的条目还是所有与谓词匹配的布尔值。 在这种情况下所有电影都来自imdb.com前250名因此“ allMatch”将返回true 。 但是并非所有电影都被评为PG因此“ allMatch”返回false 。 因为至少有一部电影被评为PG所以PG评级谓词的“ anyMatch”返回true 而N / A评级谓词的“ anyMatch”返回false因为即使底层Set没有一部电影也具有MpaaRating.NA评级。 接下来显示运行此代码的输出。 anyMatch and allMatchAll movies in IMDB Top 250? true
All movies rated PG? false
Any movies rated PG? true
Any movies not rated? false轻松确定最小和最大 本文中将Stream的强大功能应用于集合操作的最后一个示例演示了Stream.reduceBinaryOperator与BinaryOperator的两个不同实例的结合使用 Integer :: min和Integer :: max 。 private void demonstrateMinMaxReductions()
{printHeader(Oldest and Youngest via reduce);// Specifying both Predicate for .map and BinaryOperator for .reduce with lambda expressionsfinal OptionalInteger oldestMovie movies.stream().map(movie - movie.getYearReleased()).reduce((a,b) - Integer.min(a,b));out.println(Oldest movie was released in (oldestMovie.isPresent() ? oldestMovie.get() : Unknown));// Specifying both Predicate for .map and BinaryOperator for .reduce with method referencesfinal OptionalInteger youngestMovie movies.stream().map(Movie::getYearReleased).reduce(Integer::max);out.println(Youngest movie was released in (youngestMovie.isPresent() ? youngestMovie.get() : Unknown));
} 这个复杂的示例说明了如何使用Integer.min(int,int)在基础Set找到最旧的电影以及使用Integer.max(int,int)在Set找到最新的电影。 这是通过先用完成Stream.map得到一个新的Stream的Integer由每个发行年份前提是S Movie在原Stream 。 此Stream的Integer当时的具有Stream.reduce(BinaryOperation)与静态执行的操作Integer用作方法BinaryOperation 。 对于此代码清单我在计算最旧的电影 Integer.min(int,int) 时故意在Predicate和BinaryOperation中使用了lambda表达式并在计算最新电影时使用了Predicate和BinaryOperation方法引用代替了lambda表达式 Integer.max(int,int) 。 这证明lambda表达式或方法引用可以在许多情况下使用。 接下来显示运行上述代码的输出 Oldest and Youngest via reduceOldest movie was released in 1980
Youngest movie was released in 2010结论 JDK 8 Streams引入了一种强大的机制来处理Collections。 与直接使用Collections相比这篇文章侧重于使用Streams带来的可读性和简洁性但是Streams也具有潜在的性能优势。 这篇文章试图使用常见的集合处理习惯用法作为Streams带给Java的简洁性的示例。 在此过程中还讨论了与使用JDK流相关的一些关键概念。 使用JDK 8 Streams最具挑战性的部分是习惯了新概念和新语法例如lambda表达式和方法引用但是在玩了几个示例后很快就学到了这些内容。 一名对概念和语法有很丰富经验的Java开发人员可以探索Stream API的方法以获取比本博文中所示的针对Streams并因此针对基于Streams的集合执行的操作更长的列表。 其他资源 这篇文章的目的是基于简单但相当普遍的collections操纵示例简要介绍JDK 8流。 要更深入地了解JDK 8流以及有关JDK 8流如何使Collections操作更容易的更多想法请参见以下文章 使用Java SE 8流处理数据第1部分 第2部分使用Java SE 8流处理数据 本杰明·温特伯格的Java 8流教程 David Hartveld 的Stream API简介 Java 8 Streams入门 Java Tutorial的Collections on Streams 聚合操作 Java Tutorial的Collections 减少流 Java Tutorial的Collections on Streams 并行性 Lambda表达式的语法 方法参考 翻译自: https://www.javacodegeeks.com/2015/01/stream-powered-collections-functionality-in-jdk-8.html