当前位置: 移动技术网 > IT编程>开发语言>Java > java8Stream

java8Stream

2020年04月02日  | 移动技术网IT编程  | 我要评论
Stream 介绍 java8添加了一个抽象流Stream,可以让我们像写sql一样操作集合元素。Stream将要处理的元素看做是一种流,在管道中传输,并进行处理,最后由终止操作得到处理的结果。 什么是Stream? Stream是一个来自特定元素队列并支持聚合操作 元素是具体类型的对象,形成一个 ...

stream

介绍

java8添加了一个抽象流stream,可以让我们像写sql一样操作集合元素。stream将要处理的元素看做是一种流, 在管道中传输,并进行处理,最后由终止操作得到处理的结果。

什么是stream?

stream是一个来自特定元素队列并支持聚合操作

  • 元素是具体类型的对象,形成一个队列。
  • 数据源是流的来源。
  • 聚合操作是类似sql一样的操作,比如filter, map, reduce, find, match, sorted等。
  • stream自己不会存储元素。
  • stream不会改变源对象。
  • stream操作是延迟执行的。

创建流

串行流

stream():即单线程的方式去操作流

并行流

parallelstream():即多线程方式去操作流

@test
	public void test() {
		//1通过collection提供的stream()和parallelstream()方法
		list<string> list = arrays.aslist("a","b","c");
		stream<string> stream1 = list.stream();
		stream<string> stream2 = list.parallelstream();
		
		//2通过arrays的静态方法stream()
		string[] strs= {"a","b","c"};
		stream<string> stream3 = arrays.stream(strs);
		
		//3通过stream类中的静态方法of()
		stream<string> stream4 = stream.of("a","b","c");
		
		//4通过stream类的iterate方法生成无限流
		stream<integer> stream5 = stream.iterate(0, (x)->x+1);
		
		//5通过stream的generate方法生成无限流
		stream.generate(()->math.random());
		
	}

中间操作

过滤

使用 filter(predicate<? super t> predicate)来按照一定规则对流中元素进行过滤

@test
	public void test() {
		list<integer> list = arrays.aslist(1,2,3,4,5);
		stream<integer> stream = list.stream();
		stream = stream.filter((x)->x.compareto(2)>0);
		
		stream.foreach(system.out::println);
	}
输出:
3
4
5

@test
	public void test2() {
		list<integer> list = arrays.aslist(1,2,3,4,5);
		stream<integer> stream = list.stream();
		stream = stream.filter(
				(x)->{
			system.out.println(x);
			return x.compareto(2)>0;}
			);
	}
结果:没有任何输出,这也就是前面说的stream操作是延迟执行的,只有当终止操作这些中间操作才会依次执行

截断

使元素的个数不超过指定的数目

@test
	public void test() {
		list<integer> list = arrays.aslist(1,2,3,4,5);
		stream<integer> stream = list.stream();
		stream=stream.limit(3);
		stream.foreach(system.out::println);
	}
输出:
1
2
3
可以看到只输出了给定个元素

跳过元素

跳过流中前几个元素

@test
	public void test4() {
		list<integer> list = arrays.aslist(1,2,3,4,5);
		stream<integer> stream = list.stream();
		stream=stream.skip(2);
		stream.foreach(system.out::println);
	}
输出:
3
4
5
跳过了前两个元素

唯一筛选

两个元素通过hashcode()判断两个元素是否相同

@test
	public void test5() {
		list<integer> list = arrays.aslist(1,2,3,4,5,5);
		stream<integer> stream = list.stream();
		stream.distinct().foreach(system.out::println);
	}
输出:
1
2
3
4
5

映射

map(method)接受一个方法,把流中的元素按照方法进行转换

@test
	public void test() {
		list<string> list = arrays.aslist("a","b","c");
		stream<string> stream = list.stream();
		stream=stream.map((x)->x.touppercase());
		stream.foreach(system.out::println);
	}
输出:
a
b
c

flatmap(method)也是接受一个函数作为参数,但是与map,不同的是如果这个函数生成的本来就是流,它会把函数生成流中的元素加到流中

//这个函数本身就生成流
public static stream<character> tostream(string s){
  list<character> list=new arraylist<character>();
  char[] chs = s.tochararray();
  for (char c : chs) {
    list.add(c);
  }
  stream<character> stream = list.stream();
  return stream;
}
@test
public void test() {
  list<string> list = arrays.aslist("aaa","bbb","ccc");
  stream<stream<character>> stream = 
  //由于函数本身就生成流,所以流中加入的还是流
  list.stream().map(streamtest::tostream);
  //遍历的时候需要先从流中取出流,在遍历
  stream.foreach((s)->s.foreach(system.out::println));
}

//然而我们可以使用flatmap进行改进
@test
public void test() {
  list<string> list = arrays.aslist("aaa","bbb","ccc");
  list.stream().flatmap(streamtest::tostream).foreach(system.out::println);
}
输出:
a
a
a
b
b
b
c
c
c

终止操作

所有匹配

当所有元素都匹配时,allmatch(predicate<? super t> predicate)才会返回true

@test
public void test() {
  list<string> list = arrays.aslist("aaa","bbb","ccc");
  boolean allmatch = list.stream().allmatch((s)->s.length()>2);
  system.out.println(allmatch);
}
输出:
true

任一匹配

当stream中任一一个元素匹配时,anymatch(predicate<? super t> predicate)返回true

@test
public void test() {
  list<string> list = arrays.aslist("aaa","bbb","ccc");
  boolean anymatch = list.stream().anymatch((s)->s.equals("bbb"));
  system.out.println(anymatch);
}
输出:
true

所有不匹配

当stream中所有的元素都不匹配时,nonematch(predicate<? super t> predicate)返回true

@test
public void test() {
  list<string> list = arrays.aslist("aaa","bbb","ccc");
  boolean nonematch = list.stream().nonematch((s)->s.equals("ddd"));
  system.out.println(nonematch);
}
输出:
true

第一个元素

返回当前流中的第一个元素

@test
public void test() {
  list<integer> list = arrays.aslist(1,2,3,4,5);
  optional<integer> findfirst = list.stream().findfirst();
  system.out.println(findfirst.get());
}
输出:
1

任一一个元素

返回当前流中的任一一个元素

@test
public void test() {
  list<integer> list = arrays.aslist(1,2,3,4,5);
  optional<integer> findany = list.stream().findany();
  system.out.println(findany.get());
}
输出:
1

//使用并行流试试
@test
public void test13() {
	list<integer> list = arrays.aslist(1,2,3,4,5);
	optional<integer> findany =   		list.parallelstream().findany();
	system.out.println(findany.get());
}
输出:
3

流中元素个数

返回流中的元素个数

@test
public void test14() {
  list<integer> list = arrays.aslist(1,2,3,4,5);
  long count = list.stream().count();
  system.out.println(count);
}
输出:
5

流中的最大值

返回流中元素的最大值

@test
public void test15() {
  list<integer> list = arrays.aslist(1,2,3,4,5);
  optional<integer> max = list.stream().max(integer::compare);
  system.out.println(max.get());
}
输出:
5

流中的最小值

返回流中的最小值

@test
public void test16() {
  list<integer> list = arrays.aslist(1,2,3,4,5);
  optional<integer> min = list.stream().min(integer::compare);
  system.out.println(min.get());
}
输出:
1

规约

将流中的元素反复结合得到一个最终值

@test
public void test() {
  list<integer> list = arrays.aslist(1,2,3,4,5);
  optional<integer> reduce = list.stream().reduce(integer::sum);
  system.out.println(reduce.get());

  integer reduce2 = list.stream().reduce(0, (x,y)->{
    system.out.println(x+"->"+y);
    return x+y;
  });
  system.out.println(reduce2);
}
输出:
15
0->1
1->2
3->3
6->4
10->5
15

可以看到当使用(t identity, binaryoperator accumulator)时,identity即为最初和流中元素进行运算的,所以值不能为空,所以返回的不是optional

收集

将流转换成其他形式

@test
public void test() {
  list<integer> list = arrays.aslist(1,2,3,4,5,5);
  set<integer> collect = list.stream().collect(collectors.toset());
  system.out.println(collect);
}
输出:
[1, 2, 3, 4, 5]

@test
public void test() {
		list<integer> list = arrays.aslist(1,2,3,4,5,5);
		optional<integer> collect = list.stream().collect(collectors.maxby(integer::compareto));
		system.out.println(collect.get());
}
输出:
5

class stu{
	string name;
	integer age;
	string gender;
	public stu(string name, integer age, string gender) {
		super();
		this.name = name;
		this.age = age;
		this.gender = gender;
	}
	public string getname() {
		return name;
	}
	public void setname(string name) {
		this.name = name;
	}
	public integer getage() {
		return age;
	}
	public void setage(integer age) {
		this.age = age;
	}
	public string getgender() {
		return gender;
	}
	public void setgender(string gender) {
		this.gender = gender;
	}
	@override
	public string tostring() {
		return "stu [name=" + name + ", age=" + age + ", gender=" + gender + "]";
	}
	
}
//一级分组
@test
	public void test() {
		list<stu> list = arrays.aslist(
				new stu("张三",20,"男"),
				new stu("李四",22,"女"),
				new stu("王五",18,"男"),
				new stu("赵六",20,"女"),
				new stu("田七",22,"女")
				);
		map<string, list<stu>> collect = 				list.stream().collect(collectors.groupingby(stu::getgender));
		system.out.println(collect);
	}
输出:
{女=[stu [name=李四, age=22, gender=女], stu [name=赵六, age=20, gender=女], stu [name=田七, age=22, gender=女]], 男=[stu [name=张三, age=20, gender=男], stu [name=王五, age=18, gender=男]]}

//二级分组
@test
public void test21() {
  list<stu> list = arrays.aslist(
    new stu("张三",20,"男"),
    new stu("李四",22,"女"),
    new stu("王五",18,"男"),
    new stu("赵六",20,"女"),
    new stu("田七",22,"女")
  );
  map<integer, map<string, list<stu>>> collect = list.stream()
    .collect(collectors.groupingby(stu::getage, collectors.groupingby(stu::getgender)));
  system.out.println(collect);
}
输出:
{18={男=[stu [name=王五, age=18, gender=男]]}, 20={女=[stu [name=赵六, age=20, gender=女]], 男=[stu [name=张三, age=20, gender=男]]}, 22={女=[stu [name=李四, age=22, gender=女], stu [name=田七, age=22, gender=女]]}}

//分区
@test
public void test22() {
  list<stu> list = arrays.aslist(
    new stu("张三",20,"男"),
    new stu("李四",22,"女"),
    new stu("王五",18,"男"),
    new stu("赵六",20,"女"),
    new stu("田七",22,"女")
  );
  map<boolean, list<stu>> collect = list.stream()
    .collect(collectors.partitioningby((e)->((stu)e).getage()>20));
  system.out.println(collect);
}
输出:
{false=[stu [name=张三, age=20, gender=男], stu [name=王五, age=18, gender=男], stu [name=赵六, age=20, gender=女]], true=[stu [name=李四, age=22, gender=女], stu [name=田七, age=22, gender=女]]}

如您对本文有疑问或者有任何想说的,请 点击进行留言回复,万千网友为您解惑!

相关文章:

验证码:
移动技术网