一、Stream流
1.獲取Stream流的方式
Stream (單列)集合.stream();
Stream Stream.of(容器);
注意事項:流對象只能用一次。如果多次使用,需要單獨獲取流對象
示例代碼:
public class Demo01GetStream {
public static void main(String[] args) {
//把集合轉換爲Stream流
List<String> list = new ArrayList<>();
Stream<String> stream1 = list.stream();
Set<String> set = new HashSet<>();
Stream<String> stream2 = set.stream();
Map<String,String> map = new HashMap<>();
//獲取鍵,存儲到一個Set集合中
Set<String> keySet = map.keySet();
Stream<String> stream3 = keySet.stream();
//獲取值,存儲到一個Collection集合中
Collection<String> values = map.values();
Stream<String> stream4 = values.stream();
//獲取鍵值對(鍵與值的映射關係 entrySet)
Set<Map.Entry<String, String>> entries = map.entrySet();
Stream<Map.Entry<String, String>> stream5 = entries.stream();
//把數組轉換爲Stream流
Stream<Integer> stream6 = Stream.of(1, 2, 3, 4, 5);
//可變參數可以傳遞數組
Integer[] arr = {1,2,3,4,5};
Stream<Integer> stream7 = Stream.of(arr);
String[] arr2 = {"a","bb","ccc"};
Stream<String> stream8 = Stream.of(arr2);
}
}
2.Stream流的常用方法-forEach
forEach(Consumer<T>); 用於遍歷容器(終結方法)
示例代碼:
public class Demo02Stream_forEach {
public static void main(String[] args) {
//獲取一個Stream流
Stream<String> stream = Stream.of("張三", "李四", "王五", "趙六", "田七");
//使用Stream流中的方法forEach對Stream流中的數據進行遍歷
stream.forEach(name->System.out.println(name));
System.out.println("=======================");
ArrayList<Integer> list = new ArrayList<>();
list.add(5);
list.add(4);
list.add(3);
list.add(2);
list.add(1);
//獲取Stream流
Stream<Integer> stream2 = list.stream();
//遍歷集合
stream2.forEach(i -> System.out.println(i));
}
}
3.Stream流的常用方法-filter
filter(Predicate<t>); 用於過濾條件(延遲方法)
示例代碼:
public class Demo03Stream_filter {
public static void main(String[] args) {
//創建一個Stream流
Stream<String> stream = Stream.of("張三丰", "張翠山", "趙敏", "周芷若", "張無忌");
//對Stream流中的元素進行過濾,只要姓張的人
Stream<String> stream2 = stream.filter((String name)->{return name.startsWith("張");});
//遍歷stream2流
stream2.forEach(name-> System.out.println(name));
System.out.println("========================");
ArrayList<Integer> list = new ArrayList<>();
list.add(5);
list.add(4);
list.add(3);
list.add(2);
list.add(1);
//只要集合中的偶數
Stream<Integer> stream3 = list.stream();
stream3.filter(num->num % 2 == 0).forEach(i-> System.out.println(i));
}
}
4.Stream流的常用方法-map
map(Function<T,R>); 用於數據類型轉換(延遲方法)
示例代碼:
public class Demo04Stream_map {
public static void main(String[] args) {
//獲取一個String類型的Stream流
Stream<String> stream = Stream.of("1", "2", "3", "4");
//使用map方法,把字符串類型的整數,轉換(映射)爲Integer類型的整數
Stream<Integer> stream2 = stream.map((String s)->{
return Integer.parseInt(s);
});
//遍歷Stream2流
stream2.forEach(i-> System.out.println(i));
System.out.println("====================");
ArrayList<Integer> list = new ArrayList<>();
list.add(5555);
list.add(44);
list.add(3);
list.add(22222);
list.add(1111);
//通過Stream流完成:1將集合中的數字轉成字符串類型的數字。2將字符串類型的數字長度大於3的保存到一個流中。3進行遍歷
Stream<Integer> stream3 = list.stream();
stream3.map(i->i + "").filter(s->s.length() >= 3).forEach(num->System.out.println(num));
}
}
5.Stream流的常用方法-count
long count(); 獲取流中的數據個數(終結方法)
示例代碼:
public class Demo05Stream_count {
public static void main(String[] args) {
//獲取一個Stream流
ArrayList<Integer> list = new ArrayList<>();
list.add(1);
list.add(2);
list.add(3);
list.add(4);
list.add(5);
list.add(6);
list.add(7);
Stream<Integer> stream = list.stream();
long count = stream.count();
System.out.println(count);//7
System.out.println("============");
ArrayList<Integer> list2 = new ArrayList<>();
list2.add(5555);
list2.add(44);
list2.add(3);
list2.add(22222);
list2.add(1111);
//通過Stream流完成:1將集合中的數字轉成字符串類型的數字。2將字符串類型的數字長度大於3的保存到一個流中。3統計滿足條件的元素個數
Stream<Integer> stream3 = list2.stream();
long count2 = stream3.map(i->i + "").filter(s->s.length() >= 3).count();
System.out.println(count2);
}
}
6.Stream流的常用方法-limit
limit(long num); 截取指定個數的元素(延遲方法)
示例代碼:
public class Demo06Stream_limit {
public static void main(String[] args) {
//獲取一個Stream流
String[] arr = {"美羊羊","喜洋洋","懶洋洋","灰太狼","紅太狼"};
Stream<String> stream = Stream.of(arr);
//使用limit對Stream流中的元素進行截取,只要前3個元素
Stream<String> stream2 = stream.limit(3);
//遍歷stream2流
stream2.forEach(name-> System.out.println(name));
System.out.println("=============");
ArrayList<Integer> list2 = new ArrayList<>();
list2.add(5555);
list2.add(44);
list2.add(3);
list2.add(22222);
list2.add(1111);
//通過Stream流完成:1將集合中的數字轉成字符串類型的數字。
// 2將字符串類型的數字長度大於3的保存到一個流中。3將長度爲3的字符串數字只需要保存前兩個元素。4遍歷
Stream<Integer> stream3 = list2.stream();
stream3.map(i->i + "").filter(s->s.length() >= 3).limit(2).forEach(s-> System.out.println(s));
}
}
7.Stream流的常用方法-skip
skip(long num); 跳過指定的元素個數(延遲方法)
示例代碼:
public class Demo07Stream_skip {
public static void main(String[] args) {
//獲取一個Stream流
String[] arr = {"美羊羊","喜洋洋","懶洋洋","灰太狼","紅太狼"};
Stream<String> stream = Stream.of(arr);
//使用skip方法跳過前3個元素
Stream<String> stream2 = stream.skip(3);
//遍歷stream2流
stream2.forEach(name-> System.out.println(name));
System.out.println("===============");
ArrayList<Integer> list2 = new ArrayList<>();
list2.add(5555);
list2.add(44);
list2.add(3);
list2.add(22222);
list2.add(1111);
//通過Stream流完成:1將集合中的數字轉成字符串類型的數字。
// 2將字符串類型的數字長度大於3的保存到一個流中。3將長度爲3的字符串數字只需要保存前兩個元素。
// 4將之前保留了前兩個元素的流中,跳過第一個。 5遍歷
Stream<Integer> stream3 = list2.stream();
stream3.map(i->i + "").filter(s->s.length() >= 3).limit(2).skip(1).forEach(s-> System.out.println(s));
}
}
8.Stream流的常用方法-concat
concat(Stream1,Stream2); 將多個流對象拼接(延遲方法)
示例代碼:
public class Demo08Stream_concat {
public static void main(String[] args) {
//創建一個Stream流
Stream<String> stream1 = Stream.of("張三丰", "張翠山", "趙敏", "周芷若", "張無忌");
//獲取一個Stream流
String[] arr = {"美羊羊","喜洋洋","懶洋洋","灰太狼","紅太狼"};
Stream<String> stream2 = Stream.of(arr);
//把以上兩個流組合爲一個流
Stream<String> concat = Stream.concat(stream1, stream2);
//遍歷concat流
concat.forEach(name-> System.out.println(name));
}
}
9.集合的案例-傳統方式
略~
10.集合的案例-Stream流的方式
public class Demo02StreamTest {
public static void main(String[] args) {
//第一支隊伍
ArrayList<String> one = new ArrayList<>();
one.add("迪麗熱巴");
one.add("宋遠橋");
one.add("蘇星河");
one.add("石破天");
one.add("石中玉");
one.add("老子");
one.add("莊子");
one.add("洪七公");
//1. 第一個隊伍只要名字爲3個字的成員姓名;存儲到一個新集合中。
//2. 第一個隊伍篩選之後只要前3個人;存儲到一個新集合中。
Stream<String> oneStream = one.stream().filter(name -> name.length() == 3).limit(3);
//第二支隊伍
ArrayList<String> two = new ArrayList<>();
two.add("古力娜扎");
two.add("張無忌");
two.add("趙麗穎");
two.add("張三丰");
two.add("尼古拉斯趙四");
two.add("張天愛");
two.add("張二狗");
//3. 第二個隊伍只要姓張的成員姓名;存儲到一個新集合中。
//4. 第二個隊伍篩選之後不要前2個人;存儲到一個新集合中。
Stream<String> twoStream = two.stream().filter(name -> name.startsWith("張")).skip(2);
//5. 將兩個隊伍合併爲一個隊伍;存儲到一個新集合中。
//6. 根據姓名創建Person對象;存儲到一個新集合中。
//7. 打印整個隊伍的Person對象信息。
Stream.concat(oneStream,twoStream).map(name->new Person(name)).forEach(p-> System.out.println(p));
}
}
二、方法引用
1.使用格式
調用方法(對象::方法名);
2.格式解釋
調用方法(需要傳遞一個對象::一個該對象中的具體方法名);
等效於:
重寫了抽象方法,在方法體中,去執行傳遞過來的那個對象中的具體的方法
3.示例代碼:
public class Demo01Printable {
//定義一個方法,參數傳遞Printable接口,對字符串進行打印
public static void printString(Printable p){
p.print("HelloWorld");
}
public static void main(String[] args) {
//調用printString方法,方法的參數Printable是一個函數式接口,所以可以傳遞Lambda
printString((String s)->{
System.out.println(s);
});
/*
分析:
Lambda表達式的目的,打印參數傳遞的字符串
把參數s,傳遞給了System.out對象,調用out對象中的方法println對字符串進行了輸出
注意:
1.System.out對象是已經存在的
2.println方法也是已經存在的
所以我們可以使用方法引用來優化Lambda表達式
可以使用System.out方法直接引用(調用)println方法
*/
printString(System.out::println);
}
}
4.對象的方法引用
public class Demo01ObjectMethodReference {
//定義一個方法,方法的參數傳遞Printable接口
public static void printString(Printable p){
p.print("Hello");
}
public static void main(String[] args) {
//調用printString方法,方法的參數Printable是一個函數式接口,所以可以傳遞Lambda表達式
printString((String s)->{
//創建MethodRerObject對象
MethodRerObject obj = new MethodRerObject();
//調用MethodRerObject對象中的成員方法printUpperCaseString,把字符串按照大寫輸出
obj.printUpperCaseString(s);
});
/*
使用方法引用優化Lambda
對象是已經存在的MethodRerObject
成員方法也是已經存在的printUpperCaseString
所以我們可以使用對象名引用成員方法
*/
//創建MethodRerObject對象
MethodRerObject obj = new MethodRerObject();
printString(obj::printUpperCaseString);
}
}
5.靜態方法引用
格式:調用方法(類名::方法名);
示例代碼:
public class Demo01StaticMethodReference {
//定義一個方法,方法的參數傳遞要計算絕對值的整數,和函數式接口Calcable
public static int method(int number,Calcable c){
return c.calcAbs(number);
}
public static void main(String[] args) {
//調用method方法,傳遞計算絕對值得整數,和Lambda表達式
int number = method(-10,(int n)->{
//對參數進行絕對值得計算並返回結果
return Math.abs(n);
});
System.out.println(number);
/*
使用方法引用優化Lambda表達式
Math類是存在的
abs計算絕對值的靜態方法也是已經存在的
所以我們可以直接通過類名引用靜態方法
*/
int number2 = method(-10,Math::abs);
System.out.println(number2);
}
}
6.引用子父類關係的父類方法
格式:調用方法(super::方法名);
示例代碼:
public class Man extends Human{
//子類重寫父類sayHello的方法
@Override
public void sayHello() {
System.out.println("Hello 我是Man!");
}
//定義一個方法參數傳遞Greetable接口
public void method(Greetable g){
g.greet();
}
public void show(){
/*
使用super引用類的成員方法
super是已經存在的
父類的成員方法sayHello也是已經存在的
所以我們可以直接使用super引用父類的成員方法
*/
method(super::sayHello);
}
public static void main(String[] args) {
new Man().show();
}
}
7.引用本類的方法
格式:調用方法(this::方法名);
示例代碼:
public class Husband {
//定義一個買房子的方法
public void buyHouse(){
System.out.println("北京二環內買一套四合院!");
}
//定義一個結婚的方法,參數傳遞Richable接口
public void marry(Richable r){
r.buy();
}
//定義一個非常高興的方法
public void soHappy(){
//調用結婚的方法,方法的參數Richable是一個函數式接口,傳遞Lambda表達式
/* marry(()->{
//使用this.成員方法,調用本類買房子的方法
this.buyHouse();
});*/
/*
使用方法引用優化Lambda表達式
this是已經存在的
本類的成員方法buyHouse也是已經存在的
所以我們可以直接使用this引用本類的成員方法buyHouse
*/
marry(this::buyHouse);
}
public static void main(String[] args) {
new Husband().soHappy();
}
}
8.引用構造方法
格式:調用方法(對象::new);
示例代碼:
public class Demo {
//定義一個方法,參數傳遞姓名和PersonBuilder接口,方法中通過姓名創建Person對象
public static void printName(String name,PersonBuilder pb){
Person person = pb.builderPerson(name);
System.out.println(person.getName());
}
public static void main(String[] args) {
//調用printName方法,方法的參數PersonBuilder接口是一個函數式接口,可以傳遞Lambda
printName("迪麗熱巴",(String name)->{
return new Person(name);
});
/*
使用方法引用優化Lambda表達式
構造方法new Person(String name) 已知
創建對象已知 new
就可以使用Person引用new創建對象
*/
printName("古力娜扎",Person::new);//使用Person類的帶參構造方法,通過傳遞的姓名創建對象
}
}
9.引用數組構造方法
格式:調用方法(數組::new);
示例代碼:
public class Demo {
/*
定義一個方法
方法的參數傳遞創建數組的長度和ArrayBuilder接口
方法內部根據傳遞的長度使用ArrayBuilder中的方法創建數組並返回
*/
public static int[] createArray(int length, ArrayBuilder ab){
return ab.builderArray(length);
}
public static void main(String[] args) {
//調用createArray方法,傳遞數組的長度和Lambda表達式
int[] arr1 = createArray(10,(len)->{
//根據數組的長度,創建數組並返回
return new int[len];
});
System.out.println(arr1.length);//10
/*
使用方法引用優化Lambda表達式
已知創建的就是int[]數組
數組的長度也是已知的
就可以使用方法引用
int[]引用new,根據參數傳遞的長度來創建數組
*/
int[] arr2 =createArray(10,int[]::new);
System.out.println(Arrays.toString(arr2));
System.out.println(arr2.length);//10
}
}
函數式編程、方法引用、Lambda表達式【總結】
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.