java-流式編程


流式編程

 流的一個核心好處是,它使得程序更加短小並且更易理解。

public class Demo1 {
    public static void main(String[] args) {
        new Random(47)
//       ints() 方法產生一個流並且 ints() 方法有多種方式的重載
//      — 兩個參數限定了數值產生的邊界。這將生成一個整數流
                .ints(5,60)
                .distinct()//distinct() 來獲取它們的非重復值
                .limit(7)//使用 limit() 方法獲取前 7 個元素
                .sorted()//使用 sorted() 方法排序
//                forEach() 方法遍歷輸出,它根據傳遞給它的函數對每個
//                流對象執行操作。
                .forEach(System.out::println);
//        我們傳遞了一個可以在控制台顯示每個元素的方法引用。System.out::println
    }
}

 

流操作的類型有三種:創建流,修改流元素(中間操作, Intermediate Operations),消費流元素(終端操作, Terminal Operations)。

 

創建流
public class BuildUp {
    public static void main(String[] args) {
        Stream.of("aaa","bbb","vvv").forEach(System.out::print);
        Stream.of(1111,2222,3333).forEach(System.out::print);

        //從 Map 集合中產生流數據,。然后分別調用 getKey() 和 getValue() 獲取值。
        Map<String,Double> m = new HashMap<>();
        m.put("AA",1.1);
        m.put("BB",1.3);
        m.put("DDD",3.1);
        m.put("CCC",2.1);

//我們首先調用 entrySet() 產生一個對象流,每個對象都包含一個 key 鍵以及與其相關聯的 value 值
//        將對象作為e參數傳到后面,
        m.entrySet().stream().map(e -> e.getKey()+":"+
                e.getValue()).forEach(System.out::println);
    }
}

 

generate()

 

/*
Supplier 接口有一個方法就是get
 */
public class Generate implements Supplier<String>{
    Random rand = new Random(47);
    char[] letters = "ABCDEFGHIJK".toCharArray();
//    重寫接口中的函數,返回String類型值
    public String get(){
//        在指定的數組里面挑選字母
//        Random.nextInt() 的參數代表可以接受的最大的隨機數范圍
        return "" + letters[rand.nextInt(letters.length)];
    }

    public static void main(String[] args) {
        String  word = Stream.generate(new Generate()).limit(20)
                .collect(Collectors.joining());
        System.out.println(word);
        System.out.println("#######################");
        Stream.generate(() -> "done").limit(3)
                .forEach(System.out::println);

    }
}

 

 

Stream.iterate()

static <T> Stream<T> iterate(T seed, UnaryOperator<T> f)
返回有序無限連續 Stream由函數的迭代應用產生 f至初始元素 seed ,產生 Stream包括 seedf(seed)f(f(seed)) ,等 

以種子(第一個參數)開頭,並將其傳給方法(第二個參數)。方法的結果將添加到流,並存儲作為第一個參數用於下次調用 iterate()

Stream<T> skip(long n)
在丟棄流的第一個 n元素后,返回由該流的 n元素組成的流。

 

public class Fibonacci {
    int x =1;
//    匿名函數
    Stream<Integer> numbers(){
//        lambada表達式的函數
        return Stream.iterate(0,i ->{
            int result = x +i;
            x = i;
            return result;
        });
    }

    public static void main(String[] args) {
        new Fibonacci().numbers()
                .skip(10)
                .limit(10)
                .forEach(System.out::println);
    }


}
/*
斐波那契數列就是簽兩個數相加得到寫一個元素
55
89
144
233
377
610
987
1597
2584
418
 */

 

 

流的建造者模式

 

static <T> Stream.Builder<T> builder()
返回一個 Stream的構建器。

 

 

public class FileTo {
//    建立構建器,builder
    Stream.Builder<String> builder = Stream.builder();
    public FileTo(String fp) throws Exception{
        Files.lines(Paths.get(fp))
                .skip(1)
//                
                .forEach(line ->{for (String w:line.split("[ .?,]+"))//以上面做分割
                    builder.add(w);//分割完的部分加入流構建器里面
                });
    }
    Stream<String> stream(){
        return builder.build();
    }

    public static void main(String[] args) throws Exception {
//        實例化流對象
        new FileTo("src/flow/FileTo.java")
                .stream()
                .limit(7)
                .map(w -> w +" ")
                .forEach(System.out::print);
    }
}
/*
 import java nio file Files; import 
 */

注意,構造器會添加文件中的所有單詞(除了第一行,它是包含文件路徑信息的注釋),但是其並沒有調用 build()。只要你不調用 stream() 方法,就可以繼續向 builder 對象中添加單詞。

在該類的更完整形式中,你可以添加一個標志位用於查看 build() 是否被調用,並且可能的話增加一個可以添加更多單詞的方法。在 Stream.Builder 調用 build() 方法后繼續嘗試添加單詞會產生一個異常。

 

Arrays.stream()

 Arrays 類中含有一個名為 stream() 的靜態方法用於把數組轉換成為流

 

public class Demo2 {
    public static void main(String[] args) {
        ArrayList<String> list = new ArrayList<>();
        list.add("AAA");
        list.add("BBB");
        list.add("CCC");
        list.add("DDD");
        list.add("EEE");
        System.out.println(list);

        list.stream().forEach(System.out::println);
    }
}

 

 

stream() 同樣可以產生 IntStream,LongStream 和 DoubleStream。

 

public class IntLongDouble {

    public static void main(String[] args) {
//        int stream
        Arrays.stream(new int[] {1,2,3,4,5})
                .forEach(n -> System.out.format("%d  ",n));//lamabad表達式
        System.out.println();
        System.out.println("#######################");
        //指定從哪里開始到哪里結束,左閉右開區間
        Arrays.stream(new double[] {1.1,2.2,3.3,4.4,5.5,6.6,7.7},3,6)
                .forEach(n -> System.out.println(n));
        System.out.println("##############");

        Arrays.stream(new long[] {111111,444444,444999})
                .forEach(System.out::println);//引用

    }
}

 

中間操作跟蹤和調試

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM