Lambda

1 篇文章 0 订阅

Lambda表达式是一种特殊的匿名内部类,语法更简洁。它允许把函数作为一个方法的参数,将代码像数据一样传递。但是Lambda不会生成单独的内部类文件。

Lambda表达式的基本语法:

    <函数式接口> <变量名> = (参数1, 参数2)-> {
      // 方法体  
    };

如果形参列表为空,只用保留();

如果形参个数只有一个,()可以省略,只需要参数的名称;

形参列表的数据类型会自动推断;

如果执行语句只有一条,当没有返回值时,{}可以省略;当有返回值时,若是想省去{},则必须同时省略return。

demo展示:

package test1;

public class Demo1 {
    public static void main(String[] args) {
        // 匿名内部类
        Runnable runnable1 = new Runnable() {
            @Override
            public void run() {
                System.out.println("匿名内部类");
            }
        };
        new Thread(runnable1).start();

        // Lambda
        Runnable runnable2 = ()-> System.out.println("Lambda ...");

        new Thread(runnable2).start();
        
        // Lambda
        new Thread(()-> System.out.println("Lambda ...")).start();
    }
}

demo2:

package test2;

import java.util.Comparator;
import java.util.TreeSet;

public class demo {
    public static void main(String[] args) {
        // 匿名内部类
        Comparator<String> com = new Comparator<String>() {
            @Override
            public int compare(String o1, String o2) {
                return o1.length() - o2.length();
            }
        };
        TreeSet<String> treeSet = new TreeSet<>(com);
        
        // Lambda
        Comparator<String> com1 = (String o1, String o2)-> {
                return o1.length() - o2.length();
        };
        TreeSet<String> treeSet1 = new TreeSet<>(com1);
        
        // Lambda
        Comparator<String> com2 = (o1, o2)-> o1.length() - o2.length();
        TreeSet<String> treeSet2 = new TreeSet<>(com2);
    }
}

函数式接口:如果一个接口只有一个抽象方法,则该接口称为函数式接口,可使用Lambda表达式。

demo如下:

函数式接口:

package test1;

/**
 * 函数式接口
 * 可通过FunctionalInterface注解验证是否是函数式接口
 *
 */
@FunctionalInterface
public interface Usb {
    void service();
}

主方法:

package test1;

public class test {
    public static void main(String[] args) {
        Usb mouse = new Usb() {
            @Override
            public void service() {
                System.out.println("mouse...");
            }
        };

        run(mouse);
        
        // Lambda
        Usb fan = ()-> System.out.println("fan...");
        run(fan);
    }

    public static void run(Usb usb) {
        usb.service();
    }
}

demo1 消费型接口:

package test2;

import java.util.function.Consumer;

public class ConsumerTest {
    public static void main(String[] args) {
        // 匿名内部类
        java.util.function.Consumer<Double> consumer = new java.util.function.Consumer<Double>() {
            @Override
            public void accept(Double aDouble) {
                System.out.println("消费:" + aDouble);
            }
        };

        // Lambda
        java.util.function.Consumer<Double> consumer1 = aDouble-> System.out.println("消费:" + aDouble);
        happy(consumer1, 100.0);

        // 更进一步
        happy(aDouble-> System.out.println("消费:" + aDouble), 1000.0);
    }

    // 消费型接口
    public static void happy(java.util.function.Consumer<Double> consumer, Double money) {
        consumer.accept(money);
    }
}

demo2供给型接口:

package test2;

import java.util.Random;
import java.util.function.Supplier;

public class SupplierTest {
    public static void main(String[] args) {
        // 匿名内部类
        Supplier<Integer> supplier = new Supplier<Integer>() {
            @Override
            public Integer get() {
                return new Random().nextInt();
            }
        };
        
        // Lambda
        Supplier<Integer> supplier1 = ()-> new Random().nextInt();
        getNums(supplier1, 100);
        
        // 进一步简化
        getNums(()-> new Random().nextInt(), 100);
    }

    public static int[] getNums(Supplier<Integer> supplier, int count) {
        int[] arrays = new int[count];
        for (int i = 0; i < count; i++) {
            arrays[i] = supplier.get();
        }
        return arrays;
    }
}

demo3函数式接口:

package test2;

import java.util.function.Function;

public class FunctionTest {
    public static void main(String[] args) {
        Function<String ,String> function = new Function<String, String>() {
            @Override
            public String apply(String s) {
                return s.substring(0, s.length() - 2);
            }
        };
        
        // Lambda
        Function<String ,String> function1 = s->s.substring(0, s.length() - 2);

        handleFunction(function1, "1234567890");
        
        // 更进一步
        handleFunction(s->s.substring(0, s.length() - 2), "1234567890");
    }

    public static String handleFunction(Function<String, String> function, String str) {
        return function.apply(str);
    }
}

demo4断言式接口:

package test2;

import java.util.ArrayList;
import java.util.List;
import java.util.function.Predicate;

public class PredicateTest {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        Predicate<String> predicate = new Predicate<String>() {
            @Override
            public boolean test(String s) {
                if (s.length() < 10) {
                    return true;
                }
                return false;
            }
        };
        
        // Lambda
        Predicate<String> predicate1 = s-> {
                if (s.length() < 10) {
                    return true;
                }
                return false;
        };
        
        // Lambda
        Predicate<String> predicate2 = s->(s.length() < 10);
        
        fileNames(predicate, list);
        
        // 更进一步
        fileNames(s->(s.length() < 8), list);
    }
    
    public static List<String> fileNames(Predicate<String> predicate, List<String> list) {
        List<String> resultList = new ArrayList<>();
        for (String s : list) {
            if (predicate.test(s)) {
                resultList.add(s);
            }
        }
        return resultList;
    }
}

方法引用:是Lambda表达式的一种简写形式,如果Lambd表达式方法体中只式调用一个特定的已经存在的方法,则可以使用方法引用。

常见形式:

对象::实例方法

类::静态方法

类::实例方法

类::new

demo1:

package test3;

import java.util.Comparator;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Supplier;

public class demo {
    public static void main(String[] args) {
        // 对象::实例方法
        Consumer<String> consumer = s->System.out.println(s);
        consumer.accept("haha");

        // 上述操作中,后面的方法类型与前面一致,都是有参数无返回值,因此可简写成如下方式:
        Consumer<String> consumer2 = System.out::println;
        consumer2.accept("xixi");

        // 类::静态方法
        Comparator<Integer> comparator = (t1, t2)->Integer.compare(t1, t2);
        //可写成如下方式:
        Comparator<Integer> comparator1 = Integer::compare;

        // 类::实例方法
        Function<String, String> function = e->e.toString();
        // 可写成如下方式:
        Function<String, String> function1 = String::toString;

        //类::new
        Supplier<Employee> supplier = ()->new Employee();
        Supplier<Employee> supplier1 = Employee::new;
    }
}

 Stream中保存对集合或者数组数据的操作,和集合类似,但是集合中保存的是数据。类似于工厂的流水线。

特点:

1. 自己不存储元素,只保存操作。

2. 不会改变源对象,相反,会返回一个持有结果的新Stream。

3. Stream的操作是延迟执行的,会等到需要结果的时候才执行。

使用步骤:

1. 创建流的方法

通过Collection对象的stream()或者parallelStream()方法

通过Arrays类的stream()方法

通过Stream接口的of(),iterate(),generate()方法

通过IntStream,LongStream,DoubleStream接口中的if,range,rangeColsed方法。

demo:

package test4;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Random;
import java.util.stream.IntStream;
import java.util.stream.Stream;

public class Demo {
    public static void main(String[] args) {
        // 1. 通过Collection对象的stream()或者parallelStream()方法。
        ArrayList<String> arrayList = new ArrayList<>();
        arrayList.add("xixi");
        arrayList.add("haha");
        arrayList.add("lala");
        // 串行流
        Stream<String> stringStream = arrayList.stream();
        // 遍历
        //stringStream.forEach(s->System.out.println(s));
        stringStream.forEach(System.out::println);
        System.out.println("***********************************");
        // 并行流
        Stream<String> stringStream1 = arrayList.parallelStream();
        //stringStream1.forEach(s->System.out.println(s));
        stringStream1.forEach(System.out::println);
        System.out.println("***********************************");
        // 2. 通过Arrays类的stream()方法。
        String[] array = {"111", "222", "333"};
        Stream<String> streamArrays = Arrays.stream(array);
        streamArrays.forEach(System.out::println);
        System.out.println("***********************************");
        // 3. 通过Stream接口的of(),iterate(),generate()方法。
        // 将数组变成流
        Stream<Integer> streamOf = Stream.of(1,2,3,4,5,6,7,8,9,10);
        streamOf.forEach(System.out::println);
        System.out.println("***********************************");
        // 迭代流
        Stream<Integer> streamIterate = Stream.iterate(0, x->x + 2); // 返回从0开始,每次递增2的数组
        streamIterate.limit(10).forEach(System.out::println); // 取出其中的10个数据
        System.out.println("***********************************");
        // 生成流
        Stream<Integer> streamGenerate = Stream.generate(()->new Random().nextInt(100)); //  返回100以内的随机数组成的数组
        streamGenerate.limit(10).forEach(System.out::println);

        // 4. 通过IntStream, LongStream,DoubleStream接口中的of,range,rangeColsed方法。
        System.out.println("***********************************");
        IntStream intStream = IntStream.of(10, 50, 90);
        intStream.forEach(System.out::println);
        System.out.println("***********************************");
        // range与rangeColsed的区别是range是非闭合,一rangeColsed是闭合
        IntStream.range(0,10).forEach(System.out::println);
        System.out.println("***********************************");
        IntStream.rangeClosed(0, 10).forEach(System.out::println);
    }
}

2. 中间操作

        在一个或者多个步骤中,将初始的Stream转化到另一个Stream的中间操作。

        常用操作有:filter, limit,skip,distinct,sorted,map,parallel。

demo:

package test5;

import java.util.ArrayList;

public class Demo {
    public static void main(String[] args) {
        ArrayList<Employee> arrayList = new ArrayList<>();
        arrayList.add(new Employee("wangwang1", 15000));
        arrayList.add(new Employee("wangwang2", 11000));
        arrayList.add(new Employee("wangwang3", 19000));
        // arrayList.add(new Employee("wangwang3", 19000));
        arrayList.add(new Employee("wangwang4", 14000));

        // 中间操作 filter(过滤), limit(限制),skip(跳过),distinct(去重),sorted(排序),map,parallel。
        // filter过滤
        System.out.println("********************filter******************");
        arrayList.stream().filter(e->e.getMoney() > 16000).forEach(System.out::println);
        System.out.println("********************limit******************");
        arrayList.stream().limit(2).forEach(System.out::println);
        System.out.println("********************skip******************");
        arrayList.stream().skip(1).forEach(System.out::println);
        System.out.println("********************distinct******************"); // 去重的依据是hashcode与euqal,因此Employee要重写这两个方法
        arrayList.stream().distinct().forEach(System.out::println);
        System.out.println("********************sorted******************");
        // 从小到大排列
        arrayList.stream().sorted((o1, o2)->Integer.compare(o1.getMoney(), o2.getMoney())).forEach(System.out::println);
        System.out.println("********************map******************");

        System.out.println("********************parallel******************");

    }
}

3.终止操作

        使用一个终止操作来产生一个结果,该操作会强制它之前的操作立即执行,在这之后,Stream就不能用了。终止操作有forEach,min,max,count,reduce,collect。

package test6;

import test5.Employee;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

public class Demo {
    public static void main(String[] args) {
        ArrayList<Employee> arrayList = new ArrayList<>();
        arrayList.add(new Employee("wangwang1", 15000));
        arrayList.add(new Employee("wangwang2", 11000));
        arrayList.add(new Employee("wangwang3", 19000));
        arrayList.add(new Employee("wangwang4", 14000));

        System.out.println("*************for Each**************");
        arrayList.stream()
                .filter(e->e.getMoney()>11000).forEach(System.out::println);
        System.out.println("*************min**************");
        System.out.println(arrayList.stream()
                .min((e1, e2)->Double.compare(e1.getMoney(), e2.getMoney())).get());
        System.out.println("*************max**************");
        System.out.println(arrayList.stream()
                .max((e1, e2)->Double.compare(e1.getMoney(), e2.getMoney())).get());
        System.out.println("*************count**************");
        System.out.println(arrayList.stream()
                .count());
        System.out.println("*************reduce**************");
        Optional<Integer> sum = arrayList.stream()
                            .map(e->e.getMoney())
                            .reduce((x, y)->x+y);
        System.out.println(sum.get());
        System.out.println("*************collect**************");
        List<String> list = arrayList.stream()
                .map(e->e.getName())
                .collect(Collectors.toList());
        for (String l : list) {
            System.out.println(l);
        }
    }
}

新时间API(java 8开始)与修旧时间api转换:

package test7;

import javafx.util.converter.LocalDateStringConverter;

import java.time.Duration;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Date;
import java.util.Set;

public class demo {
    public static void main(String[] args) {
        System.out.println("**********LocalDateTime**************");
        LocalDateTime localDateTime0 = LocalDateTime.now();
        LocalDateTime localDateTime1 = LocalDateTime.of(2021,8,27,8,14,39);

        System.out.println(localDateTime0);
        System.out.println(localDateTime0.getYear());

        System.out.println(localDateTime1);

        // 添加天数
        LocalDateTime localDateTime2 = localDateTime0.plusDays(10);
        System.out.println(localDateTime2);
        // 减少天数
        LocalDateTime localDateTime3 = localDateTime0.minusDays(5);
        System.out.println(localDateTime3);

        System.out.println("**********Instant:时间戳**************");
        Instant instant = Instant.now();
        System.out.println(instant.toString());
        // 从1970年到现在的时间
        System.out.println(instant.toEpochMilli());
        System.out.println(System.currentTimeMillis());
        // 添加or减少时间
        Instant instant1 = instant.plusSeconds(5);
        System.out.println(Duration.between(instant, instant1).toString());

        System.out.println("**********ZoneId:时区**************");
        Set<String> availableZoneIds = ZoneId.getAvailableZoneIds();
        for (String s : availableZoneIds) { // 打印所有时区
            System.out.println(s);
        }

        // 当前的时区
        System.out.println(ZoneId.systemDefault().toString());

        System.out.println("**********新旧时间转换**************");
        System.out.println("Date-->Instant-->LocalDateTime");

        Date date = new Date();
        System.out.println(date);
        Instant instant2 = date.toInstant();
        System.out.println(instant2);
        LocalDateTime localDateTime = LocalDateTime.ofInstant(instant2, ZoneId.systemDefault());
        System.out.println(localDateTime);

        System.out.println("LocalDateTime-->Instant-->Date");
        Instant instant3 = localDateTime.atZone(ZoneId.systemDefault()).toInstant();
        System.out.println(instant3);
        Date date1 = Date.from(instant3);
        System.out.println(date1);
        
    }
}

时间格式化:

package test7;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

public class demo2 {
    public static void main(String[] args) {
        // 创建
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        // 时间转为字符串
        String format = dateTimeFormatter.format(LocalDateTime.now());
        System.out.println(format);
        // 字符串转为时间
        LocalDateTime localDateTime = LocalDateTime.parse("2019-07-15 07:08:09", dateTimeFormatter);
        System.out.println(localDateTime);
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值