中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Java8實用技能

發布時間:2020-08-11 21:58:38 來源:ITPUB博客 閱讀:165 作者:支付寶技術團隊 欄目:編程語言

大概一年多之前,我對java8的理解還僅限一些只言片語的文章之上,后來出于對函數式編程的興趣,買了本參考書看了一遍,然后放在了書架上,后來,當我接手大客戶應用的開發工作之后,java8的一些工具,對我的效率有了不小的提升,因此想記錄一下java’8的一些常用場景,我希望這會成為一個小字典,能讓我免于頻繁翻書,但是總能找到自己想找的知識。

用于舉例的model:


@Data
public class Apple {
    private Long appleId;
    private String appleName;
    private Float appleWeight;
    private Integer appleClassic;
}

一、Java 8 Lambda 表達式

這無疑是最常用的功能之一,其實lambda表達式的作用,應該就是簡潔明了,實際上是用最短的字符,通過類型推導,語法糖等方式去對編譯器描述清楚這段代碼的功能,這和泛型有點相似,對于編程人員來說,一定程度上也提高了編程效率和代碼可讀性。

如常用的lambda表達式:
process(()->System.out.println(“this is so cool!”))

例如對蘋果重量排序:


   List<Apple> apples = Lists.newArrayList();
        for (int i = 1; i < 10; i++) {
            Apple apple = new Apple();
            apples.add(apple);
        }
        apples.sort(Comparator.comparing(Apple::getAppleWeight));
反序:
        apples.sort(Comparator.comparing(Apple::getAppleWeight).reversed());
重量相同時:比較等級:
  apples.sort(Comparator
                .comparing(Apple::getAppleWeight)
                .reversed()
謂詞復合查詢:
  Predicate<Apple> a = apple -> apple.getAppleWeight() > 10;
        weight10.or(apple -> apple.getAppleClassic() > 2)
                .and(apple -> StringUtils.equalsIgnoreCase(apple.getAppleName(), "優質蘋果"));
可以看做(a||b)&&c
函數復合:
        Function<Apple, Float> f = a -> a.getAppleWeight() + 1;
        Function<Float, Float> g = a -> a * 2;
        Function<Apple, Float> h = f.andThen(g);
    數學寫作 h=g(f(x))
  Function<Apple, Float> g = a -> a.getAppleWeight() + 1;
        Function<Float, Float> f = a -> a * 2;
        Function<Apple, Float> h = f.compose(g);
 數學寫作 h=f(g(x))

小結:java8實際上想傳遞函數,函數是什么?是一個映射,可以看做x->y,輸入x然后映射到值y的過程,
java無法擺脫一切皆是對象的思想,因此函數式依附在對象上傳遞的,因此也有了下面的說法,方法引用,以及函數式接口,讓函數隨著對象傳遞,為了函數式編程,甚至專門寫一個接口—-對象來傳遞函數。然而,函數才是主角。

二、Java 8 方法引用

方法引用十分簡單,其實也是將方法作為參數傳遞。使用::域作用符,將一段方法傳遞。
舉例:Apple::getAppleId
String::subString
System.out::println

三、Java 8 函數式接口 函數式編程

利用java進行函數式編程主要就是利用函數式接口,但是函數式接口在java8之前就有一些了,就例如多線程的runnable,但是8以前是沒有lambda表達式的,所以只能使用匿名內部類,在用過lambda表達式的人看來,那是相當臃腫的,8更新了lambda表達式,這就使函數式編程更上一層樓.

java8的函數式接口為我們傳遞函數提供了工具,我們可以自己定義函數式接口,然后讓其他人,或者是java API調用。
關于函數接口,需要記住的就是兩件事:
函數接口是行為的抽象;
函數接口是數據轉換器。

四、Java 8 Stream

在我接觸到java8流式處理的時候,我的第一感覺是流式處理讓集合操作變得簡潔了許多,通常我們需要多行代碼才能完成的操作,借助于流式處理可以在一行中實現。其本質是,將一些原本開發者需要做的處理如迭代等,放在了java庫里,讓我們只關心自己的業務邏輯,比如我們希望對一個包含整數的集合中篩選出所有的偶數,并將其封裝成為一個新的List返回,那么在java8之前,我們需要通過如下代碼實現:


過去:
List<Integer> evens = new ArrayList<>();
for (final Integer num : nums) {
    if (num % 2 == 0) {
        evens.add(num);
    }
}
stream實現:
List<Integer> evens = nums.stream().filter(num -> num % 2 == 0).collect(Collectors.toList());
我們需要取出10個等級高于3的蘋果,跳過其中兩個,按重量排序,去重,然后取出蘋果的Name,然后取出名字的每個字符:
 List<String> appleName = apples.parallelStream()
                .filter(a -> a.getAppleClassic() < 2)
                .sorted(Comparator.comparing(Apple::getAppleWeight))
                .map(Apple::getAppleName)
                .map(s -> s.split(""))
                .limit(10)
                .skip(2)
                .distinct()
                .flatMap(Arrays::stream)
                .collect(Collectors.toList());   
構造AppleId ApppleName Map:
        Map<Long, String> appleIdMap = apples.stream()
                .collect(Collectors.toMap(Apple::getAppleId, Apple::getAppleName, (s, s2) -> s.length() > s2.length() ? s : s2));
 謂詞查找:      
 if (appleName.stream().anyMatch(a -> StringUtils.equalsIgnoreCase(a, "一級蘋果")));
        if (appleName.stream().allMatch(a -> StringUtils.equalsIgnoreCase(a, "一級蘋果")));
        if (appleName.stream().noneMatch(a -> StringUtils.equalsIgnoreCase(a, "一級蘋果")));
短路查找:
        appleName.stream()
                .filter(a -> StringUtils.equalsIgnoreCase(a, "一級蘋果"))
                .findAny()
                .ifPresent(System.out::println);
findfirst在并行時限制多一些,如果不在意返回的是哪個元素,使用findAny。
求和:         
    apples.stream()
    .map(Apple::getAppleWeight)
    .reduce(0F, (a, b) -> a + b);
計數:
        apples.stream().count();

使用stream的好處:
1.更簡潔,更易讀
2.可復合,更靈活
3.可并行

五、Java 8 Optional 類

Optional著重為解決java的NPE問題是Java8提供的為了解決null安全問題的一個API。善用Optional可以使我們代碼中很多繁瑣、丑陋的設計變得十分優雅。


使用Optional,我們就可以把下面這樣的代碼進行改寫:
public static String getName(User u) {
    if (u == null)
        return "Unknown";
    return u.name;
}
不過,千萬不要改寫成這副樣子。
public static String getName(User u) {
    Optional<User> user = Optional.ofNullable(u);
    if (!user.isPresent())
        return "Unknown";
    return user.get().name;
}
這樣才是正確使用Optional的姿勢。那么按照這種思路,我們可以安心的進行鏈式調用,而不是一層層判斷了。
public static String getName(User u) {
    return Optional.ofNullable(u)
                    .map(user->user.name)
                    .orElse("Unknown");
}
看一段代碼:
public static String getChampionName(Competition comp) throws IllegalArgumentException {
    if (comp != null) {
        CompResult result = comp.getResult();
        if (result != null) {
            User champion = result.getChampion();
            if (champion != null) {
                return champion.getName();
            }
        }
    }
    throw new IllegalArgumentException("The value of param comp isn't available.");
}
讓我們看看經過Optional加持過后,這些代碼會變成什么樣子。
public static String getChampionName(Competition comp) throws IllegalArgumentException {
    return Optional.ofNullable(comp)
            .map(c->c.getResult())
            .map(r->r.getChampion())
            .map(u->u.getName())
            .orElseThrow(()->new IllegalArgumentException("The value of param comp isn't available."));
}
還有很多不錯的使用姿勢,比如為空則不打印可以這么寫:
string.ifPresent(System.out::println);

參考資料:《Java 8 in Action: Lambdas, streams, and functional-style programming》 Raoul-gabriel Urma (作者), Mario Fusco (作者), Alan Mycroft (作者)

作者:文爍
點擊 閱讀更多 查看更多詳情

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

唐山市| 定陶县| 嘉定区| 阿合奇县| 安阳市| 连平县| 昌乐县| 封丘县| 青浦区| 隆尧县| 潞西市| 瑞金市| 五寨县| 新安县| 紫云| 上虞市| 楚雄市| 泰和县| 云阳县| 棋牌| 万荣县| 诸城市| 宾阳县| 景洪市| 疏勒县| 应用必备| 临猗县| 桓台县| 龙南县| 兴山县| 中江县| 光山县| 青神县| 桂阳县| 襄城县| 天镇县| 浦县| 桐庐县| 漾濞| 昂仁县| 敦化市|