java8Stream

Stream

介紹

java8添加了一個抽象流Stream,可讓咱們像寫sql同樣操做集合元素。Stream將要處理的元素看作是一種流, 在管道中傳輸,並進行處理,最後由終止操做獲得處理的結果。java

什麼是Stream?

Stream是一個來自特定元素隊列並支持聚合操做sql

  • 元素是具體類型的對象,造成一個隊列。
  • 數據源是流的來源。
  • 聚合操做是相似sql同樣的操做,好比filter, map, reduce, find, match, sorted等。
  • Stream本身不會存儲元素。
  • Stream不會改變源對象。
  • Stream操做是延遲執行的。

建立流

串行流

stream():即單線程的方式去操做流多線程

並行流

parallelStream():即多線程方式去操做流dom

@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)來按照必定規則對流中元素進行過濾ide

@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
能夠看到只輸出了給定個元素

跳過元素

跳過流中前幾個元素this

@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)接受一個方法,把流中的元素按照方法進行轉換code

@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=女]]}
相關文章
相關標籤/搜索