Java8 Lambda 之 Collection Stream

AaronCui發表於2019-02-26

Lambda 之 Collection Stream

Collection.stream()

測試實體類

class Demo {
    private Long id;
    private String name;

    // Getters and Setters   
}

// 例項化並組成一個List
List<Demo> demos = Lists.newArrayList(new Demo(1L, "SF"), new Demo(2L, "AXE"));

1.map + collect用法

場景1:獲取List列表的所有id

No Lambda

public static List<Long> getIds(List<Demo> demos){
        List<Long> ids = Lists.newArrayList();
        for (Demo d : demos) {
            ids.add(d.getId());
        }
        return ids;
}

Lambda’s show

List<Long> ids = demos.stream().map(Demo::getId).collect(toList());

最後toList() 可以有更多的實現,比如

Set<Long> ids = demos.stream().map(Demo::getId).collect(toSet());

場景2:list變成map

有時候我們把list變成map,將多次List的O(n)遍歷變成Map的O(1)查詢,拿空間換時間

No lambda

public static Map<Long, Demo> getIds(List<Demo> demos){
        Map<Long, Demo> map = Maps.newHashMap;
        for (Demo d : demos) {
            map.put(d.getId, d);
        }
        return map;
}

Lambda‘s show

 Map<Long, Demo> map = demos.stream().collect(toMap(Demo::getId, o -> o));
 

2.filter

場景1:從List中找到name="SF"的Demo例項

No lambda

public static Demo getSpecifyDemo(String name, List<Demo> demos){

    Demo target = null;
    for (Demo demo : demos) {
        if (name.equals(demo.getName())) {
            target = demo;
        }
    }
    return target;
}
    

Lambda`s show–粗獷的老漢推車

String targetName = "SF";
Demo target = demos.stream().filter(d -> targetName.equals(d.getName())).findFirst().orElse(null);

這種寫法非常簡單,但是呼叫鏈太長,一個lambda能夠繞地球好幾圈,最好寫成以下格式,防止步子邁得太大。

Lambda`s show–優雅傳教士

Demo target = demos.stream()
            .filter(d -> targetName.equals.equals(d.getName()))
            .findFirst()
            .orElse(null);

find()的結果是Optional,Optional號稱NPE終結者,於是對於find()的結果你可以隨意使用終結者攜帶的任何武器,例如orElse(),ifPresent(),isPresent()…每個用起來都是那種噠噠噠冒藍火的,更多姿勢詳見Optional的裸體原始碼。

3.match

match()filter()的縮寫版本,返回結果只有boolean型別,返回是否匹配。

場景1:當前list中某個元素是否符合某個條件
這個例子,給出另一個用法Demo::getId

No lambda

List<String> condition = new ArrayList<>();
condition.add("SF");

public static boolean isExist(List<String> condition, List<Demo> demos){
    boolean flag = false;

    for (Demo demo : demos) {
        if (condition.contains(demo.getName())) {
            flag = true;
            break;
        }
    }

    return flag;
}

Lambda`s show 使用filter

boolean flag = demos.stream()
            .map(Demo::getName)
            .filter(condition::contains)
            .findAny()
            .isPresent();

Lambda`s show 直接使用match

boolean flag = demos.stream()
            .map(Demo::getName)
            .anyMatch(condition::contains);

相關文章