Java8出了一個Stream流式程式設計,在開發中或多或少用到接觸過。怎麼說呢!舉個例子把,一起我們在周遊一個集合的時候,我們是從外部去周遊的,然後才能拿到結果,這樣來效率就會變得相對低一點。而這個時候我們去内部去周遊集合的時候,直接從内部拿資料。減少資源消耗,提升效率。
什麼是Stream呢?
Stream它并不是一個容器,它隻是對容器的功能進行了增強,添加了很多便利的操作,例如查找、過濾、分組、排序等一系列的操作。并且有串行、并行兩種執行模式,并行模式充分的利用了多核處理器的優勢,使用fork/join架構進行了任務拆分,同時提高了執行速度。簡而言之,Stream就是提供了一種高效且易于使用的處理資料的方式。
一個普通執行流程
從這簡單的圖可以看出,總共就隻有三步,相對來說還是比較容易接受。第一步是建立Stream這個容器,然後再從這個集合或者數組中去擷取這個流。第二步則是一些中間操作,比如對資料進行處理啊。第三步則就是收集我們處理的資料。
public class Stream {
public static void main(String[] args) {
list();//傳統for周遊
bigForList();//增強for周遊
iteratorList();//使用疊代器iterator周遊
}
private static void list(){
List<Integer> list = new ArrayList<>();
list.add(1);
list.add(2);
list.add(3);
int i;
int size;
for (i=0,size=list.size(); i<size; i++){
Integer integer = list.get(i);
System.out.println(integer);
}
}
private static void bigForList(){
List<String > arrlist = new ArrayList<>();
arrlist.add("張三");
arrlist.add("李四");
arrlist.add("王二");
for (String list :arrlist){
System.out.println(list);
}
}
private static void iteratorList(){
List<String> list = new ArrayList<>();
list.add("hello");
list.add("demo");
list.add("test");
Iterator<String> iterator = list.iterator();
while (iterator.hasNext()){
String s = iterator.next();
System.out.println(s);
}
}
以上就是我們我們之前常用的三種周遊方式,可能大家更加傾向于這三種,因為我們在平時開發中或者自己練習的時候。用的比較多,也就慢慢就接受了。
Steam方式周遊
但是如果資料量一大?大量資料進行周遊的時候那個這效率,就變得低起來了。是以,Stream就出來了。首先我們看看code:
//look code
public static void main (String[] args){
//List<String> sList = Arrays.asList("zhangsan","heqing","lisi","...");建立list方式1
List<String> list = new ArrayList<String>();//建立list方式2
list.add("1");
list.add("2");
list.add("3");
/*
Iterator<String> iterator = list.iterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
*/
Stream<String> stream = list.stream();
stream.forEach(System.out::println);
List<String> list2 = new ArrayList();
list.stream().forEach(str ->{
list2.add(str);
});
System.out.println(list2);
/*
Stream<String> streams = list.parallelStream();
streams.forEach(System.out::println);
*/
Stream是順序流,由主線程按順序對流執行操作,
而parallelStream是并行流,内部以多線程并行執行的方式對流進行操作,需要注意使用并行流的前提是流中的資料處理沒有順序要求(會亂序,即使用了forEachOrdered)。
Stream結果
parallelStream結果
建立順序流
//look code
public static void main (String[] args){
List<Integer> sList = Arrays.asList(1,2,3,4,5);
//把順序流通過.parallel()轉化為并行流
Optional<Integer> findFirst = sList.stream().parallel().filter(x->x>5).findFirst();
//建立順序流
java.util.stream.Stream<String> stream = sList.stream();
//建立并接流
java.util.stream.Stream<String> stringStream = sList.parallelStream();
stream.forEach(System.out::println);
}
在Stream中提供了很多方法比如filter
在以前我們要去一個集合或者數組中篩選我們想要的資料。還要進行一系列的操作,首先建立數組或者集合,然後周遊 然後判斷,然後寫邏輯等等。。。很麻煩
public static void main(String [] args){
List list= new ArrayList<>();
list.add();
....
for(){
....
....
...
邏輯代碼等。。。。
}
}
判斷條件
但是如果用到了Stream後就沒不會有這麼判斷條件。切代碼量小了,效率高了。誰又不想少寫代碼呢?早點下班不香嗎?
廢話不多說,look code;
public static void main(String[] args){
List<Integer> list = Arrays.asList(1,2,3,4,5,52,46,48,0,12);
java.util.stream.Stream<Integer> stream= list.stream();
//通過filter過濾去,擷取list中大于12的資料
stream.filter(x -> x > 12).forEach(System.out::println);
}
//就三行代碼完成,如果按照以前的寫法,起碼10行把!
還有映射 map、flatMap等
look code
map:一個元素類型為 T 的流轉換成元素類型為 R 的流,這個方法傳入一個Function的函數式接口,接收一個泛型T,傳回泛型R,map函數的定義,傳回的流,表示的泛型是R對象;
//<R> Stream<R> map(Function<? super T, ? extends R> mapper);
public static void main(String [] args) {
Stream.of("張三:20").map(s -> {
String[] str = s.split(":");
Person person = new Person(str[0],Integer.valueOf(str[1]));
return person;
}).forEach(Person -> System.out.println(Person));
}
@Test
public void deleteAssetByOrderNum() {
List<String> orderNums = new ArrayList<>();
orderNums.add("PD0001620210804005");
orderNums.add("PD0001620210804004");
orderNums.add("PD0001620210804003");
List<String> orders = orderNums.stream().map(e -> "'"+e+"'").collect(Collectors.toList());
System.out.println(orders);
String ordersJoin = String.join(",", orders);
System.out.println(orderNums);
}
将結果前後加上單引号,然後利用String.join将數組轉換成String字元串
@Test
public void test() {
String sql = "select wfcode from aac_myfocus_tab where adnum = '60052760'";
List<Map<String, Object>> list = gdao.executeJDBCSqlQuery(sql);
System.out.println("原始資料結構:"+list.toString());
List listWfcode = new ArrayList();
List list2 = new ArrayList();
for (int i = 0; i < list.size(); i++) {
listWfcode.add(((Map<String, Object>) list.get(i)).get("WFCODE"));
}
System.out.println("解析方式1:"+listWfcode.toString());
String collect = list.stream().filter(map1 -> null != map1.get("WFCODE"))
.map(str -> str.get("WFCODE").toString())
.collect(Collectors.joining(","));
System.out.println("解析方式2:"+collect);
List<String> collect1 = list.stream().filter(map1 -> null != map1.get("WFCODE"))
.map(str ->"'"+ str.get("WFCODE").toString()+"'")
.collect(Collectors.toList());
System.out.println("解析方式3:"+collect1);
}
将String字元串轉換成數組
String str= "PD0000720210524001,PD0000720210522006";
String[] array = str.split(",");
System.out.println(array);
StringBuffer sb = new StringBuffer();
for(int i=0;i<array.length;i++) {
//System.out.println(array[i]);
sb.append("'"+array[i]+"',");
}
System.out.println(sb.toString());
System.out.println(Arrays.asList(array));
List<String> orders = Arrays.asList(array).stream().map(e -> "'"+e+"'").collect(Collectors.toList());
String ordersJoin = String.join(",", orders);
System.out.println(ordersJoin);
flatMap:接收一個函數作為參數,将流中的每個值都換成另一個流,然後把所有流連接配接成一個流。
look code
public static void main(String [] args) {
List<String> list = Arrays.asList("k,l,s,x,z","1,5,2,4,8");
List<String> newList = list.stream().flatMap(s -> {
String[] str = s.split(",");
Stream<String> stream = Arrays.stream(str);
return stream;
}).collect(Collectors.toList());
System.out.println("處理前的集合"+list);
System.out.println("處理後的集合"+newList);
}
總之呢,Stream給我們提供了非常大的幫助。隻要能夠熟練使用的話,确實能夠加速開發效率。就會覺得原來寫代碼居然是那麼好玩,easy啦。據說Stream加lamda表達式寫的代碼簡直就是像詩一樣優美。
原文出處
https://blog.csdn.net/weixin_43298696/article/details/113131204
參考文章
https://www.cnblogs.com/xiaostudy/p/11648356.html