JAVA Stream在jdk17下的例子
最近因为某些原因,又要用stream,所以耗费了一些时间,做了一些例子,以便自己后续参考。
环境:
- windows11
- jdk 17
- spring 2.6.7
Article类代码:
package study.base.lambda.stream; import java.util.ArrayList; import java.util.Arrays; import java.util.Comparator; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.stream.Collectors; import java.util.stream.Stream; import com.alibaba.fastjson2.JSON; import com.alibaba.fastjson2.JSONWriter.Feature; public class Article { private final String title; private final String author; private final List<String> tags; private final String countryCode; private final String province; private Integer price; public Integer getPrice() { return price; } public void setPrice(Integer price) { this.price = price; } public Article(String title, String author, List<String> tags, String countryCode, String province) { this.title = title; this.author = author; this.tags = tags; this.countryCode = countryCode; this.province = province; this.price=Long.valueOf(Math.round(Math.random()*1000)).intValue(); } public String getTitle() { return title; } public String getAuthor() { return author; } public List<String> getTags() { return tags; } public String getCountryCode() { return countryCode; } public String getProvince() { return province; } public Poem toPoem() { Poem p=new Poem(title,author,tags,countryCode,province); if (countryCode.equals("CN")) { p.setPrice(999); p.setBody("仰天大笑出门去"); } else { p.setPrice(872); p.setBody("我辈岂是蓬蒿人"); } return p; } public Stream<String> toTagsStream(){ return this.getTags().stream(); } /** * 通过for循环逻辑,编程上会麻烦点,但是效率上高很多 */ private static void groupByCountryAndProvince_byNormal(List<Article> articles) { Map<String, Map<String, List<Article>>> result = new HashMap<String, Map<String, List<Article>>>(); for (Article article : articles) { Map<String, List<Article>> pMap = result.get(article .getCountryCode()); if (pMap == null) { pMap = new HashMap<String, List<Article>>(); result.put(article.getCountryCode(), pMap); } List<Article> list = pMap.get(article.getProvince()); if (list == null) { list = new ArrayList<Article>(); pMap.put(article.getProvince(), list); } list.add(article); } result.forEach((cc, map) -> { System.out.println("Country Code is:" + cc); map.forEach((pc, list) -> { System.out.println(" Province Code is:" + pc); list.forEach((article) -> { System.out.println(" Article titile is:" + article.getTitle() + ",author is:" + article.getAuthor()); }); }); }); } /** * 以串行流的方式,通过Collectors做多维度的分组,非常方便,但是性能上很差 */ private static void groupByCountryAndProvince(List<Article> articles) { Map<String, Map<String, List<Article>>> result = articles.stream() .collect( Collectors.groupingBy(Article::getCountryCode, Collectors.groupingBy(Article::getProvince))); result.forEach((cc, map) -> { System.out.println("Country Code is:" + cc); map.forEach((pc, list) -> { System.out.println(" Province Code is:" + pc); list.forEach((article) -> { System.out.println(" Article titile is:" + article.getTitle() + ",author is:" + article.getAuthor()); }); }); }); } private static void groupbyCountry(List<Article> articles) { Map<String, List<Article>> result = articles.stream() .collect(Collectors.groupingBy(Article::getCountryCode)); System.out.println(JSON.toJSONString(result,Feature.PrettyFormat)); } /** * 以并行流的方式,通过Collectors做多维度的分组,性能上比串行流的效率就高很多了 * 实现方式也很简单,只需要将stream()修改为parallelStream()实现。 */ private static void groupByCountryAndProvinceParallel(List<Article> articles) { Map<String, Map<String, List<Article>>> result = articles .parallelStream().collect( Collectors.groupingBy(Article::getCountryCode, Collectors.groupingBy(Article::getProvince))); result.forEach((cc, map) -> { System.out.println("Country Code is:" + cc); map.forEach((pc, list) -> { System.out.println(" Province Code is:" + pc); list.forEach((article) -> { System.out.println(" Article titile is:" + article.getTitle() + ",author is:" + article.getAuthor()); }); }); }); } private static void map(List<Article> articles){ List<Poem> list=articles.stream().map(Article::toPoem).toList(); System.out.println(JSON.toJSONString(list,Feature.PrettyFormat)); } private static void sortByPrice(List<Article> articles){ //倒序 articles.sort(new Comparator<Article>() { @Override public int compare(Article a, Article b) { return a.getPrice().compareTo(b.getPrice())*-1; } }); System.out.println(JSON.toJSONString(articles,Feature.PrettyFormat)); } public static void main(String[] args) { /** *注:以下的市场并不科学,相对而言,因为打印耗费了大量时间。 *如果准确一些,应该给出更多的数据方可。 */ List<Article> articles = new ArrayList<Article>(); Article a1 = new Article("Hello World", "Tom", Arrays.asList("Hello", "World", "Tom"), "CN", "GD"); Article a2 = new Article("Thank you teacher", "Bruce", Arrays.asList( "Thank", "you", "teacher", "Bruce"), "CN", "GX"); articles.add(a1); articles.add(a2); long start = System.currentTimeMillis(); groupByCountryAndProvince(articles); long end = System.currentTimeMillis(); System.out.println("串行流分组使用时长(毫秒):" + (end - start) + "\n"); start = System.currentTimeMillis(); groupByCountryAndProvinceParallel(articles); end = System.currentTimeMillis(); System.out.println("并行流分组使用时长(毫秒):" + (end - start) + "\n"); start = System.currentTimeMillis(); groupByCountryAndProvince_byNormal(articles); end = System.currentTimeMillis(); System.out.println("普通分组使用时长(毫秒):" + (end - start)); start = System.currentTimeMillis(); map(articles); end = System.currentTimeMillis(); System.out.println("转换使用时长(毫秒):" + (end - start)); // 按照国家分组 groupbyCountry(articles); //按照价格排序 System.out.println("-----------------------排序--n"); sortByPrice(articles); //flatMap System.out.println("----------------------flatmap------------------"); List<String> tags5=articles.stream().flatMap(i->i.getTags().stream()).map(v->v.toLowerCase()).sorted().collect(Collectors.toList()); System.out.println(JSON.toJSONString(tags5, Feature.PrettyFormat)); } }
Poem类代码:
package study.base.lambda.stream; import java.util.List; public class Poem extends Article { private String body; public String getBody() { return body; } public void setBody(String body) { this.body = body; } public Poem(String title, String author, List<String> tags, String countryCode, String province) { super(title, author, tags, countryCode, province); } }
运行结果:
Country Code is:CN Province Code is:GX Article titile is:Thank you teacher,author is:Bruce Province Code is:GD Article titile is:Hello World,author is:Tom 串行流分组使用时长(毫秒):13 Country Code is:CN Province Code is:GX Article titile is:Thank you teacher,author is:Bruce Province Code is:GD Article titile is:Hello World,author is:Tom 并行流分组使用时长(毫秒):3 Country Code is:CN Province Code is:GX Article titile is:Thank you teacher,author is:Bruce Province Code is:GD Article titile is:Hello World,author is:Tom 普通分组使用时长(毫秒):1 [ { "author":"Tom", "body":"仰天大笑出门去", "countryCode":"CN", "price":999, "province":"GD", "tags":[ "Hello", "World", "Tom" ], "title":"Hello World" }, { "author":"Bruce", "body":"仰天大笑出门去", "countryCode":"CN", "price":999, "province":"GX", "tags":[ "Thank", "you", "teacher", "Bruce" ], "title":"Thank you teacher" } ] 转换使用时长(毫秒):159 { "CN":[ { "author":"Tom", "countryCode":"CN", "price":27, "province":"GD", "tags":[ "Hello", "World", "Tom" ], "title":"Hello World" }, { "author":"Bruce", "countryCode":"CN", "price":570, "province":"GX", "tags":[ "Thank", "you", "teacher", "Bruce" ], "title":"Thank you teacher" } ] } -----------------------排序--n [ { "author":"Bruce", "countryCode":"CN", "price":570, "province":"GX", "tags":[ "Thank", "you", "teacher", "Bruce" ], "title":"Thank you teacher" }, { "author":"Tom", "countryCode":"CN", "price":27, "province":"GD", "tags":[ "Hello", "World", "Tom" ], "title":"Hello World" } ] ----------------------flatmap------------------
[
"bruce",
"hello",
"teacher",
"thank",
"tom",
"world",
"you"
]
这里有两点需要注意:
1.flatMap -- 按照原文的意思就是把每个成员再拆解为一个流,之后每个子流被放入主流,子流立刻关闭。二流子,或者是二维流。但都不是非常贴却。
通过这个函数,可以把原来数组中的每个成员的某个属性变扁平(变宽)。
articles.stream().flatMap(i->i.getTags().stream()).map(v->v.toLowerCase()).sorted().collect(Collectors.toList());
上面这里例子的意思是:list变为串流,取出流中每个tags,并把tags转为子流,这个子流合并到主流(新建)。新的主流把流中每个元素转小写,最后排序并还原为list。
所以,当有一些特别操作的时候,stream的确可以节省不少代码,特别熟悉了之后。
2.JSON.toJSONString(tags5, JSONWriter.Feature.PrettyFormat);
//flatMap
System.out.println("----------------------flatmap------------------");
List<String> tags5=articles.stream().flatMap(i->i.getTags().stream()).map(v->v.toLowerCase()).sorted().collect(Collectors.toList());
System.out.println(JSON.toJSONString(tags5, JSONWriter.Feature.PrettyFormat))
有关fastjson的引入:
<dependency> <groupId>com.alibaba.fastjson2</groupId> <artifactId>fastjson2</artifactId> <version>2.0.8</version> </dependency>