JAVA Stream在jdk17下的例子


最近因为某些原因,又要用stream,所以耗费了一些时间,做了一些例子,以便自己后续参考。

环境:

  1. windows11
  2. jdk 17
  3. 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 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 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 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 toTagsStream(){
        return this.getTags().stream();
    }

    /**
     * 通过for循环逻辑,编程上会麻烦点,但是效率上高很多
     */
    private static void groupByCountryAndProvince_byNormal(List
articles) { Map>> result = new HashMap>>(); for (Article article : articles) { Map> pMap = result.get(article .getCountryCode()); if (pMap == null) { pMap = new HashMap>(); result.put(article.getCountryCode(), pMap); } List
list = pMap.get(article.getProvince()); if (list == null) { list = new ArrayList
(); 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
articles) { Map>> 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
articles) { Map> result = articles.stream() .collect(Collectors.groupingBy(Article::getCountryCode)); System.out.println(JSON.toJSONString(result,Feature.PrettyFormat)); } /** * 以并行流的方式,通过Collectors做多维度的分组,性能上比串行流的效率就高很多了 * 实现方式也很简单,只需要将stream()修改为parallelStream()实现。 */ private static void groupByCountryAndProvinceParallel(List
articles) { Map>> 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
articles){ List list=articles.stream().map(Article::toPoem).toList(); System.out.println(JSON.toJSONString(list,Feature.PrettyFormat)); } private static void sortByPrice(List
articles){ //倒序 articles.sort(new Comparator
() { @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
articles = new ArrayList
(); 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 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 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 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.fastjson2groupId>
      <artifactId>fastjson2artifactId>
      <version>2.0.8version>
dependency>