Lambda表达式(三)

2019-11-08  本文已影响0人  jarWorker

Stream API

A squence ofelement supporting sequential and parallel affregate oprations Stream 是一组用来操作数组、集合的API

Stream 的特点

  1. 不是数据结构,没有内部存储
  2. 不支持索引访问
  3. 延迟计算
  4. 支持并行
  5. 很容易生成数组或者集合(List,Set)
  6. 支持过滤,查找,转换,汇总等操作

Stream 运行机制

Stream常用API

流的创建

  1. 通过数组
  2. 通过集合
  3. 通过Stream.generate方法来创建
  4. 通过Stream.iterate方法来创建
  5. 其他API(比如文件,字符串)

中间操作

  1. 过滤 filter
  2. 去重 distinct
  3. 排序 sorted
  4. 截取 limit、skip
  5. 转换 map/flatMap
  6. 其他 peek

终止操作

  1. 循环 forEach
  2. 计算 min、max、count
  3. 匹配 anyMatch、allMatch、noneMatch、findFirst、findAny
  4. 汇聚 reduce
  5. 收集器 toArray collect

流的创建

package lambda2;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.List;
import java.util.stream.IntStream;
import java.util.stream.Stream;

/**
 * 流的创建
 *
 */
public class CreateStream {
    /**
     * 通过数组
     */
    static void gen1() {
        Integer[] arr= {1,2,3,4};
       Stream<Integer> stream=Stream.of(arr);
       stream.forEach(System.out::println);
    }
    /**
     * 通过集合
     */
    static void gen2() {
        String[] arr= {"a","b","1","2","3"};
        List<String> list=Arrays.asList(arr) ;
       Stream<String> stream=list.stream();
       stream.forEach(System.out::println);
    }
    /**
     * 通过Stream.generate方法来创建
     */
    static void gen3() {
        Stream<String> stream=Stream.generate(()-> "a");//无止境的流,因为流没有终止
        //stream.limit(10);截取流,取前10个
        stream.limit(10).forEach(System.out::println);
    }
    /**
     * 通过Stream.iterate方法来创建
     */
    static void gen4() {
        Stream<Integer> stream=Stream.iterate(1, x->x+1);//无止境的流,因为流没有终止
        //stream.limit(10);截取流,取前10个
        stream.limit(10).forEach(System.out::println);
    }
    
    /**
     * 通过其他方式(字符串)
     */
    static void gen5() {
        String str="jarWorker";
        IntStream stream=str.chars();//转换成intStream流
        //void forEach(IntConsumer action);相当于conSumer:输入
        stream.forEach(x->System.out.println(x));
        //stream.forEach(System.out::println);//方法的引用
    }
    /**
     * 通过其他方式(读取文件)
     * @throws IOException 
     */
    static void gen6() throws IOException {
        
        String path="f:/InstanceMethod.java";
        File file=new File(path);
        if(file.exists()) {
            file.delete();
        }
        if(!file.exists()) {
            boolean flag=file.createNewFile();
            if(flag) {
                FileOutputStream out=new FileOutputStream(file,true); 
                String content="package lambda1;\r\n" + 
                        "import java.util.function.Supplier;\r\n" + 
                        "/**\r\n" + 
                        " * 实例方法引用\r\n" + 
                        " * 如果函数式接口恰巧可以通过调用一个实例的实例方法来实现,就可以使用调动实例方法来引用\r\n" + 
                        " */\r\n" + 
                        "public class InstanceMethod {\r\n" + 
                        "   /**\r\n" + 
                        "    * 实例方法\r\n" + 
                        "    * \r\n" + 
                        "    * @return\r\n" + 
                        "    */\r\n" + 
                        "   private String insert() {\r\n" + 
                        "       return \"hello lambda\";\r\n" + 
                        "   }\r\n" + 
                        "   \r\n" + 
                        "public static void main(String[] args) {\r\n" + 
                        "   Supplier<String> s = () -> {\r\n" + 
                        "       return new InstanceMethod().insert();\r\n" + 
                        "   };\r\n" + 
                        "   System.out.println(\"lambda表达式:\" + s.get());\r\n" + 
                        "   // 方法的引用\r\n" + 
                        "   Supplier<String> s1 = new InstanceMethod()::insert;\r\n" + 
                        "   System.out.println(\"方法的引用:\" + s1.get());\r\n" + 
                        " \r\n" + 
                        "}\r\n" + 
                        "}";
                //这里设置为了utf-8
                out.write(content.getBytes("utf-8"));
                
                } 
            }
        
        //这里可能会涉及编码的问题,尽量让文件的编码格式为utf-8
        Stream<String> stream= Files.lines(Paths.get(path));
        stream.forEach(System.out::println);
    }
    public static void main(String[] args) throws IOException{
        gen1();
        gen2();
        gen3();
        gen4();
        gen5();
        gen6();
    }
}


中间操作

package lambda2;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.function.Supplier;
import java.util.stream.Stream;

/**
 * 
 * 中间操作
 *
 */
public class Middle {
    /**
     * 过滤:filter
     */
    static void filterMiddle() {

        List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6);
        Stream<Integer> stream = list.stream();
        stream.filter((x) -> {
            System.out.println("进入此方法");
            return x % 2 == 1;
        }).forEach(System.out::println);// 代码没有执行forEach前并不会打印出任何东西,包括“进入此方法”,因为并没有终止流
        //stream.forEach(System.out::println);因为一个 Stream 只可以使用一次
    }
    
    /**
     * 去重:distinct
     */
    static void distinctMiddle() {

        List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 5);
        list.stream().distinct().forEach(System.out::println);
    }
    
    /**
     * 排序:sort
     */
    static void sortedMiddle() {

        List<Integer> list = Arrays.asList(1, 2, 6, 4, 5, 5,3);
        //以下做了去重和排序两个中间操作,说明说一个Stream的中间操作可以是多个
        list.stream().distinct().sorted().forEach(System.out::println);//正序
        
        list.stream().distinct().sorted(Comparator.reverseOrder()).forEach(System.out::println);//倒序
    }
    
    /**
     * 截取: limit、skip
     */
    static void InterceptionMiddle() {

        List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6);
        
         //跳过1,2
        list.stream().skip(2).forEach(System.out::println);

         //截取 1, 2
        list.stream().limit(2).forEach(System.out::println);
        
        list.stream().limit(2).skip(2).forEach(System.out::println);
    }
    /**
     * 转换: map/flatMap
     */
    static void conversionMiddle() {

        List<String> list = Arrays.asList("1","2","3");
        
        
        list.stream().map(x->x).forEach(System.out::println);//还是字符串
        //转换成int类型
        list.stream().mapToInt(x->Integer.valueOf(x)).forEach(System.out::println);//已经是int类型
        
        Supplier<List<List<String>>> s=ArrayList::new;
        List<List<String>> list1=s.get();
        List<String> l1 = Arrays.asList("1","3");
        List<String> l2 = Arrays.asList("2","4");
        list1.add(l1);
        list1.add(l2);
        
        //flatMap 大致上的意思就是有很多层的嵌套
        list1.stream().flatMap((x)->x.stream()).forEach(System.out::println);//还是字符串
        
        list1.stream().flatMapToInt((x)->x.stream().mapToInt(v->Integer.valueOf(v))).forEach(System.out::println);//已经是int类型
        
    }
    /**
     * 其他: peek
     */
    static void otherMiddle() {
        //peek和map的区别
        //peek接收一个没有返回值的λ表达式,可以做一些输出,外部处理等。map接收一个有返回值的λ表达式,之后Stream的泛型类型将转换为map参数λ表达式返回的类型
        
        Supplier<List<List<String>>> s=ArrayList::new;
        List<List<String>> list1=s.get();
        List<String> l1 = Arrays.asList("1","3");
        List<String> l2 = Arrays.asList("2","4");
        list1.add(l1);
        list1.add(l2);
        
        //下面的两个结果是一样的,只遍历了list1后没有继续往下遍历
        //peek方法接收一个Consumer的入参,没有返回值,而map方法的入参为 Function,有返回值
        list1.stream().peek((x)->x.stream()).forEach(System.out::println);
        
        list1.stream().peek((x)->x.stream().mapToInt(Integer::valueOf)).forEach(System.out::println);
        
    }
    
public static void main(String[] args) {
    filterMiddle();
    distinctMiddle();
    sortedMiddle();
    InterceptionMiddle() ;
    conversionMiddle();
    otherMiddle() ;
    
}

}

终止操作

package lambda2;

import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * 
 * 终止操作
 *
 */
public class Termination {
    static List<Integer>  number=Arrays.asList(1,2,3,4,5,6,7);
    
    /**
     * 循环
     * foreach
     */
    static void termination1() {
        Stream<Integer> stream = number.stream();
        stream.forEach(System.out::println);
    }
    
    /**
     * 计算
     * min
     */
    static void termination2() {
        Stream<Integer> stream = number.stream();
        int min=stream.min((a,b)->a-b).get();
        System.out.println(min);
    }
    /**
     * 计算
     * max
     */
    static void termination3() {
        Stream<Integer> stream = number.stream();
        int max=stream.max((a,b)->a-b).get();
        System.out.println(max);
    }
    
    /**
     * 计算
     * count
     */
    static void termination4() {
        Stream<Integer> stream = number.stream();
        long count= stream.count();
        System.out.println(count);
    }
    
    /**
     * 匹配
     * anyMatch
     */
    static void termination5() {
        Stream<Integer> stream = number.stream();
        boolean flag =stream.anyMatch(x->x.equals(10));
        System.out.println(flag);
    }
    
    /**
     * 匹配
     * allMatch
     */
    static void termination6() {
        Stream<Integer> stream = number.stream();
        boolean flag =stream.allMatch(x->x==1||x==2||x==3||x==4||x==5||x==6||x==7);
            
        
        System.out.println(flag);
    }
    /**
     * 匹配
     * noneMatch
     */
    static void termination7() {
        Stream<Integer> stream = number.stream();
        boolean flag =stream.noneMatch(x->x==10);
            
        System.out.println(flag);
    }
    
    /**
     * 匹配
     * findFirst
     */
    static void termination8() {
        Stream<Integer> stream = number.stream();
        int first =stream.sorted(Comparator.reverseOrder()).parallel().findFirst().orElse(5);
            
        System.out.println(first);
    }
    /**
     * 匹配
     * findAny
     * 
     * findAny并不是随机地选一个,如果是数据较少,串行地情况下,一般会返回第一个结果,如果是并行的情况,那就不能确保是第一个
     */
    static void termination9() {
        Stream<Integer> stream = number.stream();
        Optional<Integer> op =stream.sorted(Comparator.reverseOrder()).parallel().findAny();
        Integer any=op.get();
        System.out.println(any);
    }
    /**
     * 收集器
     * toArray collect
     * 
     */
    static void termination10() {
        List<Integer> list1=Stream.iterate(1, x->x+1).limit(50).collect(Collectors.toList());
        
        Object[] array=Stream.iterate(1, x->x+1).limit(50).toArray();
    
    }
    /**
     * 汇聚
     * reduce
     * 
     */
    static void termination11() {
        Stream<Integer> stream = number.stream();
        int result=stream.reduce((a,b)->a+b).get();
        System.out.println(result);
    }

    public static void main(String[] args) {
        termination1();
        termination2();
        termination3();
        termination4();
        termination5();
        termination6();
        termination7();
        termination8();
        termination9();
        termination10();
        termination11();

    }
}

并行流和串行流的转换

package lambda2;

import java.util.stream.Stream;

/**
 * 并行流和串行流的转换
 * 
 * 串行变并行 parallel()
 * 并行变串行 sequential()
 */
public class ParallelStream {
public static void main(String[] args) {
    
    
    String str="12,32,21";
    //串行变并行 parallel()
    int max1=Stream.of(str.split(",")).parallel().peek(x->{
        System.out.println(Thread.currentThread().getName());
        
    }).mapToInt(Integer::valueOf).max().getAsInt();
     
    //并行变串行 sequential()
    int max2=Stream.of(str.split(",")).parallel().mapToInt(Integer::valueOf).peek(x->{
        System.out.println(Thread.currentThread().getName());
        
    }).sequential().max().getAsInt();
    System.out.println(max1);
    System.out.println(max2);
}
}

上一篇 下一篇

猜你喜欢

热点阅读