国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

《Java8實(shí)戰(zhàn)》-第五章讀書筆記(使用流Stream-02)

liangzai_cool / 839人閱讀

摘要:第三個(gè)問題查找所有來自于劍橋的交易員,并按姓名排序。第六個(gè)問題打印生活在劍橋的交易員的所有交易額。第八個(gè)問題找到交易額最小的交易。

付諸實(shí)戰(zhàn)

在本節(jié)中,我們會(huì)將迄今學(xué)到的關(guān)于流的知識(shí)付諸實(shí)踐。我們來看一個(gè)不同的領(lǐng)域:執(zhí)行交易的交易員。你的經(jīng)理讓你為八個(gè)查詢找到答案。

找出2011年發(fā)生的所有交易,并按交易額排序(從低到高)。

交易員都在哪些不同的城市工作過?

查找所有來自于劍橋的交易員,并按姓名排序。

返回所有交易員的姓名字符串,按字母順序排序。

有沒有交易員是在米蘭工作的?

打印生活在劍橋的交易員的所有交易額。

所有交易中,最高的交易額是多少?

找到交易額最小的交易。

領(lǐng)域:交易員和交易

以下是我們要處理的領(lǐng)域,一個(gè) Traders 和 Transactions 的列表:

Trader raoul = new Trader("Raoul", "Cambridge");
Trader mario = new Trader("Mario", "Milan");
Trader alan = new Trader("Alan", "Cambridge");
Trader brian = new Trader("Brian", "Cambridge");

List transactions = Arrays.asList(
        new Transaction(brian, 2011, 300),
        new Transaction(raoul, 2012, 1000),
        new Transaction(raoul, 2011, 400),
        new Transaction(mario, 2012, 710),
        new Transaction(mario, 2012, 700),
        new Transaction(alan, 2012, 950)
);

Trader和Transaction類的定義:

public class Trader {
    private String name;
    private String city;

    public Trader(String n, String c){
        this.name = n;
        this.city = c;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getCity() {
        return city;
    }

    public void setCity(String city) {
        this.city = city;
    }

    @Override
    public String toString() {
        return "Trader{" +
                "name="" + name + """ +
                ", city="" + city + """ +
                "}";
    }
}

Transaction類:

public class Transaction {
    private Trader trader;
    private Integer year;
    private Integer value;

    public Transaction(Trader trader, Integer year, Integer value) {
        this.trader = trader;
        this.year = year;
        this.value = value;
    }

    public Trader getTrader() {
        return trader;
    }

    public void setTrader(Trader trader) {
        this.trader = trader;
    }

    public Integer getYear() {
        return year;
    }

    public void setYear(Integer year) {
        this.year = year;
    }

    public Integer getValue() {
        return value;
    }

    public void setValue(Integer value) {
        this.value = value;
    }

    @Override
    public String toString() {
        return "Transaction{" +
                "trader=" + trader +
                ", year=" + year +
                ", value=" + value +
                "}";
    }
}
首先,我們來看第一個(gè)問題:找出2011年發(fā)生的所有交易,并按交易額排序(從低到高)。
List tr2011 = transactions.stream()
                // 篩選出2011年發(fā)生的所有交易
                .filter(transaction -> transaction.getYear() == 2011)
                // 按照交易額從低到高排序
                .sorted(Comparator.comparing(Transaction::getValue))
                // 轉(zhuǎn)為集合
                .collect(Collectors.toList());

太棒了,第一個(gè)問題我們很輕松的就解決了!首先,將transactions集合轉(zhuǎn)為流,然后給filter傳遞一個(gè)謂詞來選擇2011年的交易,接著按照交易額從低到高進(jìn)行排序,最后將Stream中的所有元素收集到一個(gè)List集合中。

第二個(gè)問題:交易員都在哪些不同的城市工作過?
List cities = transactions.stream()
                // 提取出交易員所工作的城市
                .map(transaction -> transaction.getTrader().getCity())
                // 去除已有的城市
                .distinct()
                // 將Stream中所有的元素轉(zhuǎn)為一個(gè)List集合
                .collect(Collectors.toList());

是的,我們很簡單的完成了第二個(gè)問題。首先,將transactions集合轉(zhuǎn)為流,然后使用map提取出與交易員相關(guān)的每位交易員所在的城市,接著使用distinct去除重復(fù)的城市(當(dāng)然,我們也可以去掉distinct,在最后我們就要使用collect,將Stream中的元素轉(zhuǎn)為一個(gè)Set集合。collect(Collectors.toSet())),我們只需要不同的城市,最后將Stream中的所有元素收集到一個(gè)List中。

第三個(gè)問題:查找所有來自于劍橋的交易員,并按姓名排序。
List traders = transactions.stream()
                // 從交易中提取所有的交易員
                .map(Transaction::getTrader)
                // 進(jìn)選擇位于劍橋的交易員
                .filter(trader -> "Cambridge".equals(trader.getCity()))
                // 確保沒有重復(fù)
                .distinct()
                // 對(duì)生成的交易員流按照姓名進(jìn)行排序
                .sorted(Comparator.comparing(Trader::getName))
                .collect(Collectors.toList());

第三個(gè)問題,從交易中提取所有的交易員,然后進(jìn)選擇位于劍橋的交易員確保沒有重復(fù),接著對(duì)生成的交易員流按照姓名進(jìn)行排序。

第四個(gè)問題:返回所有交易員的姓名字符串,按字母順序排序。
String traderStr =
                transactions.stream()
                        // 提取所有交易員姓名,生成一個(gè) Strings 構(gòu)成的 Stream
                        .map(transaction -> transaction.getTrader().getName())
                        // 只選擇不相同的姓名
                        .distinct()
                        // 對(duì)姓名按字母順序排序
                        .sorted()
                        // 逐個(gè)拼接每個(gè)名字,得到一個(gè)將所有名字連接起來的 String
                        .reduce("", (n1, n2) -> n1 + " " + n2);

這些問題,我們都很輕松的就完成!首先,提取所有交易員姓名,生成一個(gè) Strings 構(gòu)成的 Stream并且只選擇不相同的姓名,然后對(duì)姓名按字母順序排序,最后使用reduce將名字拼接起來!

請(qǐng)注意,此解決方案效率不高(所有字符串都被反復(fù)連接,每次迭代的時(shí)候都要建立一個(gè)新
的 String 對(duì)象)。下一章中,你將看到一個(gè)更為高效的解決方案,它像下面這樣使用 joining (其
內(nèi)部會(huì)用到 StringBuilder ):

String traderStr =
                transactions.stream()
                            .map(transaction -> transaction.getTrader().getName())
                            .distinct()
                            .sorted()
                            .collect(joining());
第五個(gè)問題:有沒有交易員是在米蘭工作的?
boolean milanBased =
                transactions.stream()
                        // 把一個(gè)謂詞傳遞給 anyMatch ,檢查是否有交易員在米蘭工作
                        .anyMatch(transaction -> "Milan".equals(transaction.getTrader()
                                .getCity()));

第五個(gè)問題,依舊很簡單把一個(gè)謂詞傳遞給 anyMatch ,檢查是否有交易員在米蘭工作。

第六個(gè)問題:打印生活在劍橋的交易員的所有交易額。
transactions.stream()
                // 選擇住在劍橋的交易員所進(jìn)行的交易
                .filter(t -> "Cambridge".equals(t.getTrader().getCity()))
                // 提取這些交易的交易額
                .map(Transaction::getValue)
                // 打印每個(gè)值
                .forEach(System.out::println);

第六個(gè)問題,首先選擇住在劍橋的交易員所進(jìn)行的交易,接著提取這些交易的交易額,然后就打印出每個(gè)值。

第七個(gè)問題:所有交易中,最高的交易額是多少?
Optional highestValue =
                transactions.stream()
                        // 提取每項(xiàng)交易的交易額
                        .map(Transaction::getValue)
                        // 計(jì)算生成的流中的最大值
                        .reduce(Integer::max);

第七個(gè)問題,首先提取每項(xiàng)交易的交易額,然后使用reduce計(jì)算生成的流中的最大值。

第八個(gè)問題:找到交易額最小的交易。
Optional smallestTransaction =
                transactions.stream()
                        // 通過反復(fù)比較每個(gè)交易的交易額,找出最小的交易
                        .reduce((t1, t2) ->
                                t1.getValue() < t2.getValue() ? t1 : t2);

是的,第八個(gè)問題很簡單,但是還有更好的做法!流支持 min 和 max 方法,它們可以接受一個(gè) Comparator 作為參數(shù),指定
計(jì)算最小或最大值時(shí)要比較哪個(gè)鍵值:

Optional smallestTransaction = transactions.stream()
                                         .min(comparing(Transaction::getValue));

上面的八個(gè)問題,我們通過Stream很輕松的就完成了,真是太棒了!

數(shù)值流

我們?cè)谇懊婵吹搅丝梢允褂?reduce 方法計(jì)算流中元素的總和。例如,你可以像下面這樣計(jì)
算菜單的熱量:

int calories = menu.stream()
                    .map(Dish::getCalories)
                    .reduce(0, Integer::sum);

這段代碼的問題是,它有一個(gè)暗含的裝箱成本。每個(gè) Integer 都必須拆箱成一個(gè)原始類型,
再進(jìn)行求和。要是可以直接像下面這樣調(diào)用 sum 方法,豈不是更好?

int calories = menu.stream()
                    .map(Dish::getCalories)
                    .sum();

但這是不可能的。問題在于 map 方法會(huì)生成一個(gè) Stream 。雖然流中的元素是 Integer 類
型,但 Streams 接口沒有定義 sum 方法。為什么沒有呢?比方說,你只有一個(gè)像 menu 那樣的Stream ,把各種菜加起來是沒有任何意義的。但不要擔(dān)心,Stream API還提供了原始類型流特化,專門支持處理數(shù)值流的方法。

原始類型流特化

Java 8引入了三個(gè)原始類型特化流接口來解決這個(gè)問題: IntStream 、 DoubleStream 和
LongStream ,分別將流中的元素特化為 int 、 long 和 double ,從而避免了暗含的裝箱成本。每個(gè)接口都帶來了進(jìn)行常用數(shù)值歸約的新方法,比如對(duì)數(shù)值流求和的 sum ,找到最大元素的max。此外還有在必要時(shí)再把它們轉(zhuǎn)換回對(duì)象流的方法。要記住的是,這些特化的原因并不在于流的復(fù)雜性,而是裝箱造成的復(fù)雜性——即類似 int 和 Integer 之間的效率差異。

1.映射到數(shù)值流

將流轉(zhuǎn)換為特化版本的常用方法是 mapToInt 、 mapToDouble 和 mapToLong 。這些方法和前
面說的 map 方法的工作方式一樣,只是它們返回的是一個(gè)特化流,而不是 Stream 。例如,我們可以像下面這樣用 mapToInt 對(duì) menu 中的卡路里求和:

int calories = menu.stream()
        // 返回一個(gè)IntStream
        .mapToInt(Dish::getCalories)
        .sum();

這里, mapToInt 會(huì)從每道菜中提取熱量(用一個(gè) Integer 表示),并返回一個(gè) IntStream
(而不是一個(gè) Stream )。然后你就可以調(diào)用 IntStream 接口中定義的 sum 方法,對(duì)卡
路里求和了!請(qǐng)注意,如果流是空的, sum 默認(rèn)返回 0 。 IntStream 還支持其他的方便方法,如
max 、 min 、 average 等。

2.轉(zhuǎn)換回對(duì)象流

同樣,一旦有了數(shù)值流,你可能會(huì)想把它轉(zhuǎn)換回非特化流。例如, IntStream 上的操作只能
產(chǎn)生原始整數(shù): IntStream 的 map 操作接受的Lambda必須接受 int 并返回 int (一個(gè)
IntUnaryOperator )。但是你可能想要生成另一類值,比如 Dish 。為此,你需要訪問 Stream
接口中定義的那些更廣義的操作。要把原始流轉(zhuǎn)換成一般流(每個(gè) int 都會(huì)裝箱成一個(gè)
Integer ),可以使用 boxed 方法,如下所示:

IntStream intStream = menu.stream().mapToInt(Dish::getCalories);
Stream stream = intStream.boxed();

3.默認(rèn)值 OptionalInt

求和的那個(gè)例子很容易,因?yàn)樗幸粋€(gè)默認(rèn)值: 0 。但是,如果你要計(jì)算 IntStream 中的最
大元素,就得換個(gè)法子了,因?yàn)?0 是錯(cuò)誤的結(jié)果。如何區(qū)分沒有元素的流和最大值真的是 0 的流呢?
前面我們介紹了 Optional 類,這是一個(gè)可以表示值存在或不存在的容器。 Optional 可以用
Integer 、 String 等參考類型來參數(shù)化。對(duì)于三種原始流特化,也分別有一個(gè) Optional 原始類
型特化版本: OptionalInt 、 OptionalDouble 和 OptionalLong 。

例如,要找到 IntStream 中的最大元素,可以調(diào)用 max 方法,它會(huì)返回一個(gè) OptionalInt :

OptionalInt maxCalories = menu.stream()
                .mapToInt(Dish::getCalories)
                .max();

現(xiàn)在,如果沒有最大值的話,你就可以顯式處理 OptionalInt 去定義一個(gè)默認(rèn)值了:

int max = maxCalories.orElse(1);
數(shù)值范圍

和數(shù)字打交道時(shí),有一個(gè)常用的東西就是數(shù)值范圍。比如,假設(shè)你想要生成1和100之間的所有數(shù)字。Java 8引入了兩個(gè)可以用于 IntStream 和 LongStream 的靜態(tài)方法,幫助生成這種范圍:
range 和 rangeClosed 。這兩個(gè)方法都是第一個(gè)參數(shù)接受起始值,第二個(gè)參數(shù)接受結(jié)束值。但
range 是不包含結(jié)束值的,而 rangeClosed 則包含結(jié)束值。讓我們來看一個(gè)例子:

// 一個(gè)從1到100的偶數(shù)流 包含結(jié)束值
IntStream evenNumbers = IntStream.rangeClosed(1, 100)
        .filter(n -> n % 2 == 0);
// 從1到100共有50個(gè)偶數(shù)
System.out.println(evenNumbers.count());

這里我們用了 rangeClosed 方法來生成1到100之間的所有數(shù)字。它會(huì)產(chǎn)生一個(gè)流,然后你
可以鏈接 filter 方法,只選出偶數(shù)。到目前為止還沒有進(jìn)行任何計(jì)算。最后,你對(duì)生成的流調(diào)
用 count 。因?yàn)?count 是一個(gè)終端操作,所以它會(huì)處理流,并返回結(jié)果 50 ,這正是1到100(包括
兩端)中所有偶數(shù)的個(gè)數(shù)。請(qǐng)注意,比較一下,如果改用 IntStream.range(1, 100) ,則結(jié)果
將會(huì)是 49 個(gè)偶數(shù),因?yàn)?range 是不包含結(jié)束值的。

構(gòu)建流

希望到現(xiàn)在,我們已經(jīng)讓你相信,流對(duì)于表達(dá)數(shù)據(jù)處理查詢是非常強(qiáng)大而有用的。到目前為
止,你已經(jīng)能夠使用 stream 方法從集合生成流了。此外,我們還介紹了如何根據(jù)數(shù)值范圍創(chuàng)建
數(shù)值流。但創(chuàng)建流的方法還有許多!本節(jié)將介紹如何從值序列、數(shù)組、文件來創(chuàng)建流,甚至由生成函數(shù)來創(chuàng)建無限流!

由值創(chuàng)建流

你可以使用靜態(tài)方法 Stream.of ,通過顯式值創(chuàng)建一個(gè)流。它可以接受任意數(shù)量的參數(shù)。例
如,以下代碼直接使用 Stream.of 創(chuàng)建了一個(gè)字符串流。然后,你可以將字符串轉(zhuǎn)換為大寫,再
一個(gè)個(gè)打印出來:

Stream stream = Stream.of("Java 8 ", "Lambdas ", "In ", "Action");
stream.map(String::toUpperCase).forEach(System.out::println);

你可以使用 empty 得到一個(gè)空流,如下所示:

Stream emptyStream = Stream.empty();
由數(shù)組創(chuàng)建流

我們可以使用靜態(tài)方法 Arrays.stream 從數(shù)組創(chuàng)建一個(gè)流。它接受一個(gè)數(shù)組作為參數(shù)。例如,
我們可以將一個(gè)原始類型 int 的數(shù)組轉(zhuǎn)換成一個(gè) IntStream ,如下所示:

int[] numbers = {2, 3, 5, 7, 11, 13};
// 總和41
int sum = Arrays.stream(numbers).sum();
由文件生成流

Java中用于處理文件等I/O操作的NIO API(非阻塞 I/O)已更新,以便利用Stream API。
java.nio.file.Files 中的很多靜態(tài)方法都會(huì)返回一個(gè)流。例如,一個(gè)很有用的方法是
Files.lines ,它會(huì)返回一個(gè)由指定文件中的各行構(gòu)成的字符串流。使用我們迄今所學(xué)的內(nèi)容,我們可以用這個(gè)方法看看一個(gè)文件中有多少各不相同的詞:

long uniqueWords;
try (Stream lines = Files.lines(Paths.get(ClassLoader.getSystemResource("data.txt").toURI()),
        Charset.defaultCharset())) {
    uniqueWords = lines.flatMap(line -> Arrays.stream(line.split(" ")))
            .distinct()
            .count();
    System.out.println("uniqueWords:" + uniqueWords);
} catch (IOException e) {
    e.fillInStackTrace();
} catch (URISyntaxException e) {
    e.printStackTrace();
}

你可以使用 Files.lines 得到一個(gè)流,其中的每個(gè)元素都是給定文件中的一行。然后,你
可以對(duì) line 調(diào)用 split 方法將行拆分成單詞。應(yīng)該注意的是,你該如何使用 flatMap 產(chǎn)生一個(gè)扁平的單詞流,而不是給每一行生成一個(gè)單詞流。最后,把 distinct 和 count 方法鏈接起來,數(shù)數(shù)流中有多少各不相同的單詞。

由函數(shù)生成流:創(chuàng)建無限流

Stream API提供了兩個(gè)靜態(tài)方法來從函數(shù)生成流: Stream.iterate 和 Stream.generate 。
這兩個(gè)操作可以創(chuàng)建所謂的無限流:不像從固定集合創(chuàng)建的流那樣有固定大小的流。由 iterate和 generate 產(chǎn)生的流會(huì)用給定的函數(shù)按需創(chuàng)建值,因此可以無窮無盡地計(jì)算下去!一般來說,應(yīng)該使用 limit(n) 來對(duì)這種流加以限制,以避免打印無窮多個(gè)值。

1.迭代

我們先來看一個(gè) iterate 的簡單例子,然后再解釋:

Stream.iterate(0, n -> n + 2)
        .limit(10)
        .forEach(System.out::println);

iterate 方法接受一個(gè)初始值(在這里是 0 ),還有一個(gè)依次應(yīng)用在每個(gè)產(chǎn)生的新值上的
Lambda( UnaryOperator 類型)。這里,我們使用Lambda n -> n + 2 ,返回的是前一個(gè)元素加上2。因此,iterate方法生成了一個(gè)所有正偶數(shù)的流:流的第一個(gè)元素是初始值 0 。然后加上 2 來生成新的值 2 ,再加上 2 來得到新的值 4 ,以此類推。這種 iterate 操作基本上是順序的,因?yàn)榻Y(jié)果取決于前一次應(yīng)用。請(qǐng)注意,此操作將生成一個(gè)無限流——這個(gè)流沒有結(jié)尾,因?yàn)橹凳前葱栌?jì)算的,可以永遠(yuǎn)計(jì)算下去。我們說這個(gè)流是無界的。正如我們前面所討論的,這是流和集合之間的一個(gè)關(guān)鍵區(qū)別。我們使用limit方法來顯式限制流的大小。這里只選擇了前10個(gè)偶數(shù)。然后可以調(diào)用 forEach 終端操作來消費(fèi)流,并分別打印每個(gè)元素。

2.生成

與 iterate 方法類似, generate 方法也可讓你按需生成一個(gè)無限流。但 generate 不是依次
對(duì)每個(gè)新生成的值應(yīng)用函數(shù)的。它接受一個(gè) Supplier 類型的Lambda提供新的值。我們先來
看一個(gè)簡單的用法:

Stream.generate(Math::random)
                .limit(5)
                .forEach(System.out::println);

這段代碼將生成一個(gè)流,其中有五個(gè)0到1之間的隨機(jī)雙精度數(shù)。例如,運(yùn)行一次得到了下面
的結(jié)果:

0.8404010101858976
0.03607897810804739
0.025199243727344833
0.8368092999566692
0.14685668895309267

Math.Random 靜態(tài)方法被用作新值生成器。同樣,你可以用 limit 方法顯式限制流的大小,
否則流將會(huì)無限長。

你可能想知道, generate 方法還有什么用途。我們使用的供應(yīng)源(指向 Math.random 的方
法引用)是無狀態(tài)的:它不會(huì)在任何地方記錄任何值,以備以后計(jì)算使用。但供應(yīng)源不一定是無狀態(tài)的。你可以創(chuàng)建存儲(chǔ)狀態(tài)的供應(yīng)源,它可以修改狀態(tài),并在為流生成下一個(gè)值時(shí)使用。

我們?cè)谶@個(gè)例子中會(huì)使用 IntStream 說明避免裝箱操作的代碼。 IntStream 的 generate 方
法會(huì)接受一個(gè) IntSupplier ,而不是 Supplier 。例如,可以這樣來生成一個(gè)全是1的無限流:

IntStream ones = IntStream.generate(() -> 1);

還記得第三章的筆記中,Lambda允許你創(chuàng)建函數(shù)式接口的實(shí)例,只要直接內(nèi)聯(lián)提供方法的實(shí)
現(xiàn)就可以。你也可以像下面這樣,通過實(shí)現(xiàn) IntSupplier 接口中定義的 getAsInt 方法顯式傳遞一個(gè)對(duì)象(雖然這看起來是無緣無故地繞圈子,也請(qǐng)你耐心看):

IntStream twos = IntStream.generate(new IntSupplier(){
            @Override
            public int getAsInt(){
                return 2;
            }
        });

generate 方法將使用給定的供應(yīng)源,并反復(fù)調(diào)用 getAsInt 方法,而這個(gè)方法總是返回 2 。
但這里使用的匿名類和Lambda的區(qū)別在于,匿名類可以通過字段定義狀態(tài),而狀態(tài)又可以用
getAsInt 方法來修改。這是一個(gè)副作用的例子。我們迄今見過的所有Lambda都是沒有副作用的;它們沒有改變?nèi)魏螤顟B(tài)。

總結(jié)

這一章的東西很多,收獲也很多!現(xiàn)在你可以更高效地處理集合了。事實(shí)上,流讓你可以簡潔地表達(dá)復(fù)雜的數(shù)據(jù)處理查詢。此外,流可以透明地并行化。以下是我們應(yīng)從本章中學(xué)到的關(guān)鍵概念。
這一章的讀書筆記中,我們學(xué)習(xí)和了解到了:

Streams API可以表達(dá)復(fù)雜的數(shù)據(jù)處理查詢。

你可以使用 filter 、 distinct 、 skip 和 limit 對(duì)流做篩選和切片。

你可以使用 map 和 flatMap 提取或轉(zhuǎn)換流中的元素。

你可以使用 findFirst 和 findAny 方法查找流中的元素。你可以用 allMatch、noneMatch 和 anyMatch 方法讓流匹配給定的謂詞。

這些方法都利用了短路:找到結(jié)果就立即停止計(jì)算;沒有必要處理整個(gè)流。

你可以利用 reduce 方法將流中所有的元素迭代合并成一個(gè)結(jié)果,例如求和或查找最大元素。

filter 和 map 等操作是無狀態(tài)的,它們并不存儲(chǔ)任何狀態(tài)。 reduce 等操作要存儲(chǔ)狀態(tài)才能計(jì)算出一個(gè)值。 sorted 和 distinct 等操作也要存儲(chǔ)狀態(tài),因?yàn)樗鼈冃枰蚜髦械乃性鼐彺嫫饋聿拍芊祷匾粋€(gè)新的流。這種操作稱為有狀態(tài)操作。

流有三種基本的原始類型特化: IntStream 、 DoubleStream 和 LongStream 。它們的操作也有相應(yīng)的特化。

流不僅可以從集合創(chuàng)建,也可從值、數(shù)組、文件以及 iterate 與 generate 等特定方法創(chuàng)建。

無限流是沒有固定大小的流。

代碼

Github: chap5

Gitee: chap5

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/77057.html

相關(guān)文章

  • Java8實(shí)戰(zhàn)》-五章讀書筆記使用Stream-01)

    摘要:跳過元素流還支持方法,返回一個(gè)扔掉了前個(gè)元素的流。歸約到目前為止,我們見到過的終端操作都是返回一個(gè)之類的或?qū)ο蟮取_@樣的查詢可以被歸類為歸約操作將流歸約成一個(gè)值。通過反復(fù)使用加法,你把一個(gè)數(shù)字列表歸約成了一個(gè)數(shù)字。 使用流 在上一篇的讀書筆記中,我們已經(jīng)看到了流讓你從外部迭代轉(zhuǎn)向內(nèi)部迭代。這樣,你就用不著寫下面這樣的代碼來顯式地管理數(shù)據(jù)集合的迭代(外部迭代)了: /** * 菜單 ...

    OldPanda 評(píng)論0 收藏0
  • 《java 8 實(shí)戰(zhàn)讀書筆記 -五章 使用

    摘要:比如,你可以建立一個(gè),選出熱量超過卡路里的頭三道菜請(qǐng)注意也可以用在無序流上,比如源是一個(gè)。跳過元素流還支持方法,返回一個(gè)扔掉了前個(gè)元素的流。一般來說,應(yīng)該使用來對(duì)這種流加以限制,以避免打印無窮多個(gè)值。 一、篩選和切片 1.用謂詞篩選 Streams接口支持filter方法。該操作會(huì)接受一個(gè)謂詞(一個(gè)返回boolean的函數(shù))作為參數(shù),并返回一個(gè)包括所有符合謂詞的元素的流。例如篩選出所有...

    Richard_Gao 評(píng)論0 收藏0
  • Java8實(shí)戰(zhàn)》-讀書筆記第一章(02

    摘要:實(shí)戰(zhàn)讀書筆記第一章從方法傳遞到接著上次的,繼續(xù)來了解一下,如果繼續(xù)簡化代碼。去掉并且生成的數(shù)字是萬,所消耗的時(shí)間循序流并行流至于為什么有時(shí)候并行流效率比循序流還低,這個(gè)以后的文章會(huì)解釋。 《Java8實(shí)戰(zhàn)》-讀書筆記第一章(02) 從方法傳遞到Lambda 接著上次的Predicate,繼續(xù)來了解一下,如果繼續(xù)簡化代碼。 把方法作為值來傳遞雖然很有用,但是要是有很多類似與isHeavy...

    lushan 評(píng)論0 收藏0
  • Java8實(shí)戰(zhàn)》-第四章讀書筆記(引入Stream

    摘要:內(nèi)部迭代與使用迭代器顯式迭代的集合不同,流的迭代操作是在背后進(jìn)行的。流只能遍歷一次請(qǐng)注意,和迭代器類似,流只能遍歷一次。 流(Stream) 流是什么 流是Java API的新成員,它允許你以聲明性方式處理數(shù)據(jù)集合(通過查詢語句來表達(dá),而不是臨時(shí)編寫一個(gè)實(shí)現(xiàn))。就現(xiàn)在來說,你可以把它們看成遍歷數(shù)據(jù)集的高級(jí)迭代器。此外,流還可以透明地并行處理,你無需寫任何多線程代碼了!我會(huì)在后面的筆記中...

    _ivan 評(píng)論0 收藏0
  • Java8實(shí)戰(zhàn)》-第六章讀書筆記(用收集數(shù)據(jù)-02

    摘要:使用流收集數(shù)據(jù)分區(qū)分區(qū)是分組的特殊情況由一個(gè)謂詞返回一個(gè)布爾值的函數(shù)作為分類函數(shù),它稱分區(qū)函數(shù)。這種情況下,累加器對(duì)象將會(huì)直接用作歸約過程的最終結(jié)果。這也意味著,將累加器不加檢查地轉(zhuǎn)換為結(jié)果是安全的。 使用流收集數(shù)據(jù) 分區(qū) 分區(qū)是分組的特殊情況:由一個(gè)謂詞(返回一個(gè)布爾值的函數(shù))作為分類函數(shù),它稱分區(qū)函數(shù)。分區(qū)函數(shù)返回一個(gè)布爾值,這意味著得到的分組 Map 的鍵類型是 Boolean ...

    jcc 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<