【優(yōu)雅代碼】11-stream精選/@functional懶加載示例

【優(yōu)雅代碼】11-stream精選/@functional懶加載示例

歡迎關(guān)注b站賬號(hào)/公眾號(hào)【六邊形戰(zhàn)士夏寧】氮采,一個(gè)要把各項(xiàng)指標(biāo)拉滿的男人摇庙。該文章已在github目錄收錄。
屏幕前的大帥比大漂亮如果有幫助到你的話請(qǐng)順手點(diǎn)個(gè)贊宁改、加個(gè)收藏這對(duì)我真的很重要街佑。別下次一定了,都不關(guān)注上哪下次一定盾舌。

1.背景

主要是對(duì)@functional簡(jiǎn)單示例矿筝,復(fù)雜示例會(huì)在18~20期展示。之前在優(yōu)雅代碼系列的第3節(jié)分享過了optional的用法,這邊就不再贅述了

2.常用部分

2.1示例

該部分包含了個(gè)人日常開發(fā)中95%以上的使用場(chǎng)景棚贾,或者其變種

public static void ordinaryUsed() {
    // 并行流,會(huì)亂序
    System.out.println("Step1");
    Stream.of(1, 2, 3, 4).parallel().forEach(System.out::print);
    System.out.println();
    System.out.println("Step2");
    // 并行流+收集保證不會(huì)亂序
    Stream.of(1, 2, 3, 4).parallel().collect(Collectors.toList()).forEach(System.out::print);
    System.out.println();
    System.out.println("Step3");
    // 獲取唯一數(shù)據(jù)
    System.out.println(Stream.of(1, 2, 3, 4).filter(s -> s.equals(1)).findAny().get());
    System.out.println("Step4");
    // 條件過濾獲取新數(shù)據(jù)-list/set
    System.out.println(Stream.of(1, 2, 3, 4).filter(s -> s > 3).collect(Collectors.toList()));
    // 條件過濾獲取新數(shù)據(jù)-map
    System.out.println("Step5");
    System.out.println(new HashMap<Integer, Integer>() {{
        put(1, 1);
        put(2, 2);
        put(3, 3);
        put(4, 4);
    }}.entrySet().stream().filter(s -> s.getKey() > 3).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)));
    System.out.println("Step6");
    // list做物理分頁(yè)
    List<Integer> list = Stream.of(1, 2, 3, 4, 5).collect(Collectors.toList());
    int pageNum = 2;
    int pageSize = 3;
    System.out.println(list.stream().skip((pageNum - 1) * pageSize).limit(pageSize).collect(Collectors.toList()));
    // 循環(huán)創(chuàng)建連續(xù)數(shù)字list
    System.out.println("Step7");
    System.out.println(IntStream.range(0, 10).boxed().collect(Collectors.toList()));
    // list循環(huán)獲取索引下標(biāo)
    System.out.println("Step8");
    IntStream.range(0, list.size()).forEach(x -> System.out.print(list.get(x)));
    System.out.println();
    // list對(duì)象-轉(zhuǎn)map榆综,注意key不能相同妙痹,否則會(huì)報(bào)錯(cuò)
    System.out.println("Step9");
    System.out.println(Stream.of(TestEnum.values()).collect(Collectors.toMap(TestEnum::getCode, s -> s)));
    System.out.println("Step10");
    // list對(duì)象-轉(zhuǎn)map嵌list,根據(jù)選擇的屬性進(jìn)行合并
    System.out.println(Arrays.stream(TestEnum.values()).collect(Collectors.groupingBy(TestEnum::getDesc)));
}
  • 輸出如下
Step1
3421
Step2
1234
Step3
1
Step4
[4]
Step5
{4=4}
Step6
[4, 5]
Step7
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
Step8
12345
Step9
{1=TestEnum.EXCEL(super=EXCEL, code=1, desc=excel), 2=TestEnum.PPT(super=PPT, code=2, desc=ppt)}
Step10
{excel=[TestEnum.EXCEL(super=EXCEL, code=1, desc=excel)], ppt=[TestEnum.PPT(super=PPT, code=2, desc=ppt)]}

2.2說明

Lambda 表達(dá)式免去了使用匿名方法的麻煩

使用方法 對(duì)應(yīng)lambda表達(dá)式
object::instanceMethod (a,b,.....)->特定對(duì)象.實(shí)例方法(a,b....)
Class::statucMethod (a,b,.....)->類名.類方法(a,b....)
Class::instanceMethod (a,b,.....)->a.實(shí)例方法(b....)
Class::new (a,b,.....)->new 類名(a,b....)

3.@functional懶加載應(yīng)用

模擬場(chǎng)景1,從redis獲取數(shù)據(jù)鼻疮。
模擬場(chǎng)景2怯伊,打印日志。

/**
 * Consumer :
 * 1.主要適用于沒有返回值的,
 * 2.可以在方法內(nèi)部抽1個(gè)小方法判沟,注意該方法只能傳1個(gè)參數(shù)耿芹,且一定要簡(jiǎn)單崭篡,復(fù)雜的話還是直接抽方法,僅僅是處理代碼重復(fù)問題
 * Supplier主要適用于有返回值的
 * predicate
 * 1.和consumer類似吧秕,可以在方法內(nèi)抽小方法琉闪,也只接受一個(gè)參數(shù)
 * 2.接受傳參方式的判斷,可應(yīng)用于多個(gè)復(fù)雜判斷拆成小單元時(shí)再行組合砸彬,應(yīng)用場(chǎng)景少
 * <p>
 * 雖然只接收一個(gè)參數(shù)但可以是對(duì)象
 *
 * @author 876651109@qq.com
 * @date 2021/2/10 9:25 上午
 */
public class Delay {
    public static <T> T getFromRedisAndRefresh(String redisKey, Supplier<T> method) {
        // 從redis獲取數(shù)據(jù)
        T redisData = getKey(redisKey);
        if (redisData != null) {
            System.out.println("redis hit");
            return redisData;
        } else {
            System.out.println("redis not hit");
            T data = method.get();
            System.out.println("redis refresh");
            return data;
        }
    }

    private static <T> T getKey(String redisKey) {
        if (redisKey.equals("1")) {
            return (T) new Integer(0);
        }
        return null;
    }

    public static void showLog(int level, Consumer method) {
        // 日志級(jí)別等于3的時(shí)候輸出日志同時(shí)執(zhí)行計(jì)算颠毙,避免了傳統(tǒng)的先計(jì)算再判斷
        if (level >= 4) {
            method.accept(String.format("current level is %s", JSON.toJSONString(level)));
        }
    }

    public static void main(String[] args) throws InterruptedException {
        // 模擬場(chǎng)景1,從redis獲取數(shù)據(jù)砂碉。 
        // 輸出
        int data1 = 1;
        getFromRedisAndRefresh("1", () -> {
            // 從數(shù)據(jù)庫(kù)拿到1
            System.out.println("get From database" + data1);
            return data1;
        });
        // 不輸出
        int data2 = 2;
        getFromRedisAndRefresh("2", () -> {
            // 從數(shù)據(jù)庫(kù)拿到2
            System.out.println("get From database" + data2);
            return data2;
        });


        // 模擬場(chǎng)景2蛀蜜,打印日志。
        // 不輸出
        showLog(3, System.out::println);

        // 輸出
        showLog(4, System.out::println);
    }
}

輸出如下,代表redisKey如果是1則直接返回redis結(jié)果redisKey如果是2則沒有命中增蹭,需要去數(shù)據(jù)庫(kù)加載滴某。日志級(jí)別大于等于4的時(shí)候輸出日志同時(shí)執(zhí)行計(jì)算,避免了傳統(tǒng)的先計(jì)算再判斷

redis hit
redis not hit
get From database2
redis refresh
current level is 4

4.非常用部分

這部分就不是個(gè)人感悟了滋迈,網(wǎng)上有各種使用霎奢,這里僅列舉部分場(chǎng)景

public static void predicate() {
    Predicate<Integer> predicate = x -> x > 7;
    System.out.println(predicate.test(10)); //輸出 true
    System.out.println(predicate.test(6));  //輸出 fasle
    /**
     * 2、大于7并且
     */
    //在上面大于7的條件下杀怠,添加是偶數(shù)的條件
    predicate = predicate.and(x -> x % 2 == 0);
    System.out.println(predicate.test(6));  //輸出 fasle
    System.out.println(predicate.test(12)); //輸出 true
    System.out.println(predicate.test(13)); //輸出 fasle
    /**
     * 3椰憋、add or 簡(jiǎn)化寫法
     */
    predicate = x -> x > 5 && x < 9;
    System.out.println(predicate.test(10)); //輸出 false
    System.out.println(predicate.test(6));  //輸出 true
}

public static void reduce() {
    // 從40開始,迭代+2赔退,共20個(gè)
    List<Integer> list3 = Stream.iterate(40, n -> n + 2).limit(20).collect(Collectors.toList());
    System.out.println(list3);
    // 從10的基礎(chǔ)上全部相加
    int reducedParams = Stream.of(1, 2, 3)
            .reduce(10, (a, b) -> a + b, (a, b) -> {
                return a + b;
            });
    System.out.println(reducedParams);
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末橙依,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子硕旗,更是在濱河造成了極大的恐慌窗骑,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,183評(píng)論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件漆枚,死亡現(xiàn)場(chǎng)離奇詭異创译,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)墙基,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,850評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門软族,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人残制,你說我怎么就攤上這事立砸。” “怎么了初茶?”我有些...
    開封第一講書人閱讀 168,766評(píng)論 0 361
  • 文/不壞的土叔 我叫張陵颗祝,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我,道長(zhǎng)螺戳,這世上最難降的妖魔是什么搁宾? 我笑而不...
    開封第一講書人閱讀 59,854評(píng)論 1 299
  • 正文 為了忘掉前任,我火速辦了婚禮倔幼,結(jié)果婚禮上盖腿,老公的妹妹穿的比我還像新娘。我一直安慰自己凤藏,他們只是感情好奸忽,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,871評(píng)論 6 398
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著揖庄,像睡著了一般栗菜。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上蹄梢,一...
    開封第一講書人閱讀 52,457評(píng)論 1 311
  • 那天疙筹,我揣著相機(jī)與錄音,去河邊找鬼禁炒。 笑死而咆,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的幕袱。 我是一名探鬼主播暴备,決...
    沈念sama閱讀 40,999評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼们豌!你這毒婦竟也來了涯捻?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,914評(píng)論 0 277
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤望迎,失蹤者是張志新(化名)和其女友劉穎障癌,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體辩尊,經(jīng)...
    沈念sama閱讀 46,465評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡涛浙,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,543評(píng)論 3 342
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了摄欲。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片轿亮。...
    茶點(diǎn)故事閱讀 40,675評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖胸墙,靈堂內(nèi)的尸體忽然破棺而出我注,到底是詐尸還是另有隱情,我是刑警寧澤劳秋,帶...
    沈念sama閱讀 36,354評(píng)論 5 351
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響玻淑,放射性物質(zhì)發(fā)生泄漏嗽冒。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,029評(píng)論 3 335
  • 文/蒙蒙 一补履、第九天 我趴在偏房一處隱蔽的房頂上張望添坊。 院中可真熱鬧,春花似錦箫锤、人聲如沸贬蛙。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,514評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)阳准。三九已至,卻和暖如春馏臭,著一層夾襖步出監(jiān)牢的瞬間野蝇,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,616評(píng)論 1 274
  • 我被黑心中介騙來泰國(guó)打工括儒, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留绕沈,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 49,091評(píng)論 3 378
  • 正文 我出身青樓帮寻,卻偏偏與公主長(zhǎng)得像乍狐,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子固逗,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,685評(píng)論 2 360

推薦閱讀更多精彩內(nèi)容