java基础之lambda表达式
? ? ? ? ? ? ? ? ? ? ? ? ? ? java基礎之lambda表達式
1 什么是lambda表達式
lambda表達式是一個匿名函數,允許將一個函數作為另外一個函數的參數,將函數作為參數傳遞(可理解為一段傳遞的代碼)。
2 為什么要用lambda表達式
lambda表達式可以寫出更簡潔更靈活的代碼。先看看下面一段代碼
public class TestLambda {//匿名內部類方式@Testpublic void test() {TreeSet<Integer> set = new TreeSet<>(new Comparator<Integer>() {@Overridepublic int compare(Integer o1, Integer o2) { return Integer.compare(o1, o2);} });}//lambda方式@Testpublic void test1() {Comparator<Integer> com = (x,y)->Integer.compare(x, y);TreeSet<Integer> set = new TreeSet<>(com); }List<Person> list = Arrays.asList(new Person("小紅", 18, 5000.0), new Person("小明", 21, 6000.0),new Person("小剛", 25, 7000.0));// 傳統方式獲取年齡大于20的人@Testpublic void test2() {for (Person person : list) {if(person.getAge()>20) {System.out.println(person);}}}// lambda方式獲取年齡大于20的人@Testpublic void test3() {list.stream().filter((x)-> x.getAge()>20).forEach(System.out::println);} }?
3 lambda語法
java8中引入了操作符“->”,稱為箭頭操作符或lambda操作符,lambda用于替換匿名函數。
使用lambda表達式的前提:接口(函數式接口)中只能有一個抽象方法。
函數式接口:接口中只有一個抽象方法的接口,通過注解@Functioninterface 限定
lambda操作符將lambda表達式拆成兩個部分:
(1)左側是lambda表達式的參數列表(可以理解為抽象方法的參數)
(2)右側是lambda表達式中需要執行的功能,即lambda體(可以理解為抽象方法的實現的功能)
3.1 格式一:無參數,無返回值
()->System.out.println("Hello Lambda!");
3.2 格式二:有一個參數,無返回值(如果只有一個參數可以省略(),如果只有一條語法可以省略{})
(x)->System.out.println(x);
3.3 格式三:如果只有一個參數,小括號可以省略不寫
x -> System.out.println(x);
3.4 格式四:有兩個以上的參數,有返回值,并且 Lambda 體中有多條語句
Comparator<Integer> com = (x, y) -> {
? ? ? ? ? System.out.println("函數式接口");
? ? ? ? ? ?return Integer.compare(x, y);
};
3.5 格式五:如果 Lambda 體中只有一條語句,?return 和 大括號都可以省略不寫
Comparator<Integer> com = (x, y) -> Integer.compare(x, y);
3.6?格式六:Lambda 表達式的參數列表的數據類型可以省略不寫,因為JVM編譯器通過上下文推斷出數據類型,即“類型推斷”
(Integer x, Integer y) -> Integer.compare(x, y);
?
4 內置的四個核心函數式接口
4.1 消費型接口Consumer<T>
抽象方法:void accept(T t);
//消費型接口@Testpublic void test1() {// Consumer<Double> con = (x)-> System.out.print(x);// consumer(100, con);consumer(100,(x)-> System.out.print(x));}public void consumer(double money,Consumer<Double> con){con.accept(money);}4.2 供給型接口Supplier<T>
抽象方法:T get();
//供給型接口@Testpublic void test2() {List<Integer> randomNum = getRandomNum(10,()->new Random().nextInt(100));System.out.println(randomNum);}/*** @Description 生成指定個數的隨機數* @param count* @param su* @return int*/public List<Integer> getRandomNum(int count,Supplier<Integer> su) {List<Integer> list = new ArrayList<>();for(int i = 0;i<count;i++) {list.add(su.get());}return list;}4.3 函數式接口Function<T,R>
抽象方法:R apply(T t);
//函數式型接口@Testpublic void test3() {List<String> list = toUpperList(new ArrayList<String>(Arrays.asList("abc","df","aa","cc")),(x)-> x.toUpperCase());System.out.println(list);}/*** @Description 將集合里面的字符串轉大寫* @param list* @param fun* @return List<String>*/public List<String> toUpperList(List<String> list,Function<String,String> fun){for(int i = 0;i < list.size();i++) {String apply = fun.apply(list.get(i));list.set(i, apply);} return list; }4.4 斷言型接口Predicate<T>
抽象方法:boolean test(T t);
//斷言型接口@Testpublic void test4() {List<String> list = Remove(new ArrayList<String>(Arrays.asList("abc","df","aa","cc")),(s) -> s.length() < 2);System.out.println(list);}/*** @Description 刪除集合中長度小于2的元素* @param list* @param pre* @return List<String>*/public List<String> Remove(List<String> list,Predicate<String> pre) {Iterator<String> it = list.iterator();while(it.hasNext()) {String str = it.next();if(pre.test(str)) {list.remove(str);}}return list;}5 方法引用
5.1 方法引用
將Lambda體中的功能,已有方法方法提供了實現,可以使用方法引用(方法引用可以理解為Lambda的另一種表現形式)
方法引用分類:
(1)對象的引用::實例方法名
//對象的引用::實例方法名@Testpublic void test1() {Date date = new Date();//傳統lambda表達式Supplier<Long> su = ()-> date.getTime();System.out.println(su.get());//對象引用Supplier<Long> su1 = date::getTime;System.out.println(su1.get());}(2)類名::靜態方法名
//類名::靜態方法名@Testpublic void test2() {Comparator<Integer> com = (x,y)-> Integer.compare(x, y);System.out.println(com.compare(4, 5));Comparator<Integer> com1 = Integer::compare;System.out.println(com1.compare(4, 5));}(3)類名::實例方法名
//類名::實例方法名@Testpublic void test3() {Function<Person,String> fun = (x)-> x.show();System.out.println(fun.apply(new Person()));Function<Person,String> fun1 = Person::show;System.out.println(fun.apply(new Person()));}class Person{public String show() {return "aaa";}}注意:方法引用所引用的參數列表與返回值類型,需要與函數式接口中抽象方法的參數列表和返回值類型保持一致。若Lambda的參數列表的第一個參數,是實例方法的調用,第二個參數(或無參)是實例方法的參數是,格式:ClassName::MethodName
5.2 構造器引用
構造器中的參數列表需要與函數式中參數列表保持一致
類名::new?
//類名 :: new@Testpublic void test4() {Supplier<Person> sup = () -> new Person();System.out.println(sup.get());Supplier<Person> sup2 = Person::new;System.out.println(sup2.get());}?
6?Stream
6.1 什么是Stream
Stream流是數據管道,用于操作數據源(集合,數組)所產生的元素序列。
Stream 不是集合元素,它不是數據結構并不保存數據,它是有關算法和計算的,它更像一個高級版本的 Iterator。原始版本的 Iterator,只能顯式地一個一個遍歷元素并對其執行某些操作;高級版本的 Stream,需要對元素執行什么操作,比如 “過濾掉長度大于 10 的字符串”等,Stream 會隱式地在內部進行遍歷,做出相應的數據轉換。Stream是單向的數據只能遍歷一次。迭代器又不同的是,Stream 可以并行化操作,迭代器只能命令式地、串行化操作。
注意:①stream自己不會存儲元素;②stream不會改變對象,他會返回一個新的stream;③stream的操作是延遲的。
6.2 Stream的操作
操作步驟:①創建Stream;②中間操作;③終止操作
(1)創建流
@Testpublic void test1() {//1.Collection獲取流,獲取到的是順序流List<String> list = new ArrayList<>();Stream<String> stream = list.stream();//2.通過Arrays中的stream獲取一個數組流String[] arr = new String[5];Stream<String> stream2 = Arrays.stream(arr);//3.通過Stream類中的靜態方法ofStream<Integer> of = Stream.of(11,22,33,44,55);//4.創建無限流Stream<Integer> limit = Stream.iterate(0, (x)-> x + 1).limit(20);limit.forEach(System.out::println);//5.用Stream的generate生成Stream<Double> limit2 = Stream.generate(Math::random).limit(20);limit2.forEach(System.out::println);}(2)中間操作:
常用中間操作方法如下:
| 方法 | 描述 |
| Stream<T> filter(Predicate<? super T> predicate) | 接收Lambda,從流中排除某些元素 |
| Stream<T> limit(long maxSize) | 截斷流,使元素不超過給定數量 |
| Stream<T> skip(long n)? | ?跳過元素,返回一個扔掉了前n個元素的流,若流中元素不足n個,則返回一個流,與limit(n)互補 |
| Stream<T> distinct() | 帥選通過流所生成元素的 hashCode() 和 equals() 去除重復元素 |
| <R> Stream<R> map(Function<? super T,? extends R> mapper) | 接收一個lambda,將元素轉成成其他形式或提取信息,接收一個函數作為參數,該函數會被 應用到個元素上,并將其映射成一個新元素 |
(3)終止操作
常用終止操作如下
| 方法 | 描述 |
| boolean allMatch(Predicate<? super T> predicate) ? | 檢查是否匹配所有元素 |
| boolean anyMatch(Predicate<? super T> predicate) ? | 檢查是否至少匹配一個元素 |
| boolean noneMatch(Predicate<? super T> predicate) ? | 檢查是否沒有匹配的元素 |
| Optional<T> findFirst() ? | 返回第一個元素 |
| Optional<T> findAny() ? | 返回當前流中的任意元素 |
| long count() | 返回流中元素的總個數 |
| Optional<T> max(Comparator<? super T> comparator) ? | 返回流中最大值 |
| Optional<T> min(Comparator<? super T> comparator)? | 返回流中最小值 |
案例:
@Testpublic void test2() {List<String> list = Arrays.asList("a","d","e","b","c");//自然排序list.stream().sorted().forEach(System.out::println);//定制排序List<Person> p = new ArrayList<>();p.add(new Person("aa",18,100.0));p.add(new Person("cc",16,150.0));p.add(new Person("bb",20,180.0));p.stream().sorted((e1,e2)->{if(e1.getAge()==e2.getAge()) {return e1.getName().compareTo(e2.getName());}else {return e1.getAge()-e2.getAge();}}).forEach(System.out::println);}class Person {private String name;private int age;private double score;public Person() {}public Person(String name, int age, double score) {this.name = name;this.age = age;this.score = score;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public double getScore() {return score;}public void setScore(double score) {this.score = score;}@Overridepublic String toString() {return "Person1 [name=" + name + ", age=" + age + ", score=" + score + "]";}}?
?
?
?
總結
以上是生活随笔為你收集整理的java基础之lambda表达式的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 最右显示请求服务器不存在,修改合流任务_
- 下一篇: 2016年10月计算机网络技术,2016