Java8中新增的Stream API

測試數據:java

private static List<String> getList() {
    List<String> list = new ArrayList<>();
    list.add("a1");
    list.add("a2");
    list.add("a3");
    list.add("a4");
    list.add("b1");
    list.add("b2");
    list.add("b3");
    list.add("b4");
    return list;
}

private static List<String> getList2() {
		List<String> list = new ArrayList<>();
		list.add("1");
		list.add("2");
		list.add("3");
		list.add("4");
		return list;
}

一、迭代:

List<String> list = getList();
//Java8以前的迭代
for (String s : list) {
    System.out.println(s);
}

//Stream API的迭代
list.forEach(System.out::println);


二、過濾某些元素:

//過濾掉不以a開頭的字符串
		List<String> list = getList();
		for (Iterator<String> i = list.iterator();i.hasNext();) {
			String s = i.next();
			if(!s.startsWith("a"))
				i.remove();
		}
		System.out.println(list);
		
		//Stream API
		List<String> list2 = getList();
		list2 = list.stream().filter(s -> s.startsWith("a")).collect(Collectors.toList());
		System.out.println(list2);


三、轉換:

//String 轉換成 Integer
		List<String> list = getList2();
		List<Integer> list2 = new ArrayList<>();
		for (String s : list) {
			list2.add(Integer.valueOf(s));
		}
		System.out.println(list2);
		
		//Stream API
		List<String> list3 = getList2();
		List<Integer> list4 = list3.stream().map(Integer :: valueOf).collect(Collectors.toList());
		System.out.println(list4);


四、幾個簡單的聚合方法:

//聚合方法
		List<String> list = getList();
		List<String> list2 = getList2();
		//最大值
		Optional<String> max = list2.stream().max(String :: compareTo);
		System.out.println(max.get());
		//最小值
		Optional<String> min = list2.stream().min(String :: compareTo);
		System.out.println(min.get());
		//找到第一個以a開頭的元素
		Optional<String> first = list.stream().filter(s -> s.startsWith("a")).findFirst();
		System.out.println(first.get());
		//查找一個以a開頭的元素(不是按順序查找),parallelStream是並行執行計算的流
		Optional<String> findAny = list.parallelStream().filter(s -> s.startsWith("a")).findAny();
		System.out.println(findAny.get());
		//查找是否存在以a開頭的元素
		boolean anyMatch = list.parallelStream().anyMatch(s -> s.startsWith("a"));
		System.out.println(anyMatch);
		//是否每一個元素都是以a開頭
		boolean allMatch = list.parallelStream().allMatch(s -> s.startsWith("a"));
		System.out.println(allMatch);
		//是否每一個元素都不是以c開頭
		boolean noneMatch = list.parallelStream().noneMatch(s -> s.startsWith("c"));
		System.out.println(noneMatch);


上面大部分操做都返回一個Optional類,下面介紹安全

五、Optional的基本用法:

//Optional的基本用法
		List<String> list = getList();
		Optional<String> findAny = list.parallelStream().filter(s -> s.startsWith("a")).findAny();
		//一、顯示判斷,若是存在符合條件的元素,則取出來打印(我的不經常使用)
		if(findAny.isPresent()){
			System.out.println(findAny.get());
		}
		//二、若是存在符合條件的元素,則取出來打印,若是不存在,則什麼都不作
		findAny.ifPresent(System.out::println);
		
		Optional<String> findAny2 = list.parallelStream().filter(s -> s.startsWith("c")).findAny();
		//三、若是不存在符合條件的元素,則用""代替
		System.out.println(findAny2.orElse(""));
		//四、若是不存在符合條件的元素,則用計算的結果代替
		String orElseGet = findAny2.orElseGet(() ->{
			if(System.currentTimeMillis() % 2 == 0)
				return "a99";
			return "";
		});
		System.out.println(orElseGet);
		//五、若是不存在符合條件的元素,則拋出異常
		findAny2.orElseThrow(RuntimeException :: new);


六、收集:

//收集,把結果收集組合成MAP
		List<String> list = getList();
		Map<String, Integer> collect = list.stream().collect(Collectors.toMap(s -> s, s -> s.length()));
		System.out.println(collect);


七、並行流parallel的注意事項:

須要確保傳遞給並行流操做的函數都是線程安全的,函數

例如,這樣作會有問題:測試

List<String> list = getList();
		List<String> list2 = new ArrayList<>();
		list.parallelStream().forEach(s -> {
			//必定的轉換後封裝到另外一個list
			list2.add(s+"ff");
		}); 
		System.out.println(list.size());
		System.out.println(list2.size());

能夠改爲這樣:spa

List<String> list = getList();
		List<String> list2 = Collections.synchronizedList(new ArrayList<>());
		list.parallelStream().forEach(s -> {
			//必定的轉換後封裝到另外一個list
			list2.add(s+"ff");
		}); 
		System.out.println(list.size());
		System.out.println(list2.size());
相關文章
相關標籤/搜索