①接口中只有一個抽象想法java
②Object類中方法編程
③靜態方法api
含義:Stream是對集合對象進行各類便利、高效聚合操做或者大批量數據操做。stream藉助lambda表達式極大提升編程效率和程序可讀性ide
構成:數據源——>數據轉換——>執行操做獲取想要結果。每次轉換原有stream對象不變,返回一個新的stream對象函數
例:this
//實現將含有a、b、c三個元素的list轉換爲大寫字母放入新的list中 List<String> strs=Arrays.asList("a","b","c"); //java8以前作法 List<String> before8=new ArrayList<String>(); for(String str:strs){ before8.add(str.toUpperCase()); } //java8以後作法 List<String> after8=strs.stream().map(String ::toUpperCase).collect(Collector.toList()); //map做用是將對象轉化爲其餘類型對象
一、map():將input stream的每個元素映射成output stream的另外一個元素。--只是將原來元素作聚合等計算,但沒有if條件判斷spa
List<Integer> nums=Arrays.asList(1,2,3);
List<Integer> newNums=nums.stream().map(n->n*n).collect(Collectors.toList());
結果:[1,4,9]code
二、filter():過濾inputstream,將知足條件的元素生成outputstream ---存在if條件判斷對象
List<Integer> nums=Arrays.asList(1,2,3,4,5,6);
List<Integer> newNums=nums.stream().filter(n->n%2==0).collect(Collectors.toList());
結果:[2, 4, 6]blog
三、forEach():對每一個inputstream元素執行->後表達式
public class TestJava8 { public static void main(String[] args) { List<Integer> nums=Arrays.asList(1,2,3,4,5,6); nums.stream().forEach(n->getn(n)); nums.stream().forEach(n->getn(n*8)); } private static String getn(int n) { System.out.println("-----------"+n); return n+"dd"; } } 結果: -----------1 -----------2 -----------3 -----------4 -----------5 -----------6 -----------8 -----------16 -----------24 -----------32 -----------40 -----------48
四、reduce():做用是把stream元素組合起來
reduce格式是:reduce(參考值,操做函數),參考值會參與到後邊操做函數中;若是沒有參考值則返回的Optional[]格式
常見:sum、min、max、concat 等方法
List<Integer> lists=Arrays.asList(-3,-7,-1,5,1); lists.stream().reduce(0,Integer::sum));//結果是0-3-7-1+5+1=-5 lists.stream().reduce(Integer::sum));//結果是Optional[-5] lists.stream().reduce(Integer::sum).get());//結果是-5 lists.stream().reduce(Integer::min).get());//結果是-7 同理還有max()方法 List<String> strs=Arrays.asList("Q","W","E"); strs.stream.reduce("",String::concat)); //結果是"QWE" strs.stream.reduce("A",String:concat));//結果是"AQWE"
五、limit/skip
limit(n):返回前n個元素
skip(n):去掉前n個元素
iterate():迭代,用於從函數生成流,通常用limit()或skip()對這種流加以限制
Stream.iterate(0, n->n+3).limit(10).skip(3).forEach(System.out::println);
結果:
9
12
15
18
21
24
27
六、Match匹配,stream有三個match方法
allMatch():Stream中所有元素都符合邏輯判斷,則返回true
anyMatch():Stream中只要有一個元素都符合邏輯判斷,則返回true
noneMatch():Stream中所有元素都不符合邏輯判斷,則返回true
List<Staff> stuffs=Arrays.asList( new Staff("mkyong", 30), new Staff("jack", 27), new Staff("lawrence", 33), new Staff("lawrence", 22) ); System.out.println(stuffs.stream().allMatch(stuff->stuff.getAge()>28)); System.out.println(stuffs.stream().anyMatch(stuff->stuff.getAge()>28)); System.out.println(stuffs.stream().noneMatch(sutff->sutff.getAge()>28)); 結果: false true false
七、sort() 排序; distinct()找出不重複內容
lists.stream().filter(word -> word.length() > 0).
map(String::toLowerCase).
distinct().
sorted().
collect(Collectors.toList());
八、groupby/partitionby
List<Staff> stuffs=Arrays.asList( new Staff("mkyong", 30), new Staff("jack", 22), new Staff("lawrence", 33), new Staff("lawrence", 22) ); Map<Integer,List<Staff>> stfs=stuffs.stream().collect(Collectors.groupingBy(Staff::getAge)); //分組 for(Map.Entry<Integer, List<Staff>> entry:stfs.entrySet()) { System.out.println("key:"+entry.getKey()); System.out.println("value:"+JSON.toJSONString(entry.getValue())); } 結果: key:33 value:[{"age":33,"name":"lawrence"}] key:22 value:[{"age":22,"name":"jack"},{"age":22,"name":"lawrence"}] key:30 value:[{"age":30,"name":"mkyong"}]
含義:方法引用是用來直接訪問類或者實例的已存在的方法或者構造方法,方法引用是一個lambda表達式,其方法引用的操做符是雙冒號::
方法引用類型:
類型 | 示例 |
引用靜態方法 | ContainingClass::staticMethodName |
引用某個對象的實例方法 | containingObject::instanceMethodName |
引用某個類型的任意對象的實例方法 | ContainingType::methodName |
引用構造方法 | ClassName::new |
組成語法:ClassName::statcimethodName
諸如:String::valueOf 等價s->String.valueOf(s)
Math::pow 等價於(x,y)->math.pow(x,y)
public class Person { private LocalDate birthday; private String name; public Person(String name,LocalDate birthday) { this.name=name; this.birthday=birthday; } public LocalDate getBirthday() { return birthday; } public String getName() { return name; } public void setBirthday(LocalDate birthday) { this.birthday = birthday; } static int compareByAge(Person p1,Person p2) { //尤爲注意這裏是靜態方法,若是不是靜態方法則不能被方法引用 return p1.birthday.compareTo(p2.birthday); } } public class ReferenceDemo { public static void main(String[] args) { List<Person> persons1=Arrays.asList(new Person("zhangSan",LocalDate.of(2000, 6, 6)), new Person("wangWu",LocalDate.of(1999, 9, 20)), new Person("hanMeiMei",LocalDate.of(2001, 6, 1)) ); List<Person> persons2=Arrays.asList(new Person("zhangSan",LocalDate.of(2000, 6, 6)), new Person("wangWu",LocalDate.of(1999, 9, 20)), new Person("hanMeiMei",LocalDate.of(2001, 6, 1)) ); //lambda表達式 List<Person> pp1=persons1.stream().sorted((p1,p2)->(p1.getBirthday().compareTo(p2.getBirthday()))).collect(Collectors.toList()); //方法引用 List<Person> pp2=persons2.stream().sorted(Person::compareByAge).collect(Collectors.toList()); pp1.forEach((p)->System.out.println(JSON.toJSONString(p))); System.out.println("------------------------"); pp2.forEach((p)->System.out.println(JSON.toJSONString(p))); } } 結果: {"birthday":"1999-09-20","name":"wangWu"} {"birthday":"2000-06-06","name":"zhangSan"} {"birthday":"2001-06-01","name":"hanMeiMei"} ------------------------ {"birthday":"1999-09-20","name":"wangWu"} {"birthday":"2000-06-06","name":"zhangSan"} {"birthday":"2001-06-01","name":"hanMeiMei"}
2.2引用某個對象的實例方法
參考:https://www.ibm.com/developerworks/cn/java/j-lo-java8streamapi/