Java8新特性基础入门

1. Lambda 表达式

在JDK8之前,Java是不支持函数式编程的,所谓的函数编程,即可理解是将一个函数(也称为“行为”)作为一个参数进行传递。通常我们提及得更多的是面向对象编程,面向对象编程是对数据的抽象(各种各样的POJO类),而函数式编程则是对行为的抽象(将行为作为一个参数进行传递)。在JavaScript中这是很常见的一个语法特性,但在Java中将一个函数作为参数传递这却行不通,好在JDK8的出现打破了Java的这一限制。

Lambda表达式一共有三部分组成:
630246201802180010329061130608891.png

  1. 左侧是一个小括号,里面是要实现的抽象方法的参数,有几个参数就写几个参数名,无参可写空括号,无需声明参数类型;

  2. 中间是一个jdk8新定义的箭头符号;

  3. 右侧是一个大括号,在括号内编写抽象方法的实现内容,有参时,可直接使用左侧括号中的对应参数,与正常方法的方法体相同;

  4. 使用方式:实现只有一个抽象方法的接口时会自行匹配到该方法,在箭头左侧编写对应参数个数的参数名,箭头右侧编写方法的实现代码(代码实现为单行时可去掉大括号{})

 public static void main(String[] args) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("hello java8");
            }
        }).start();
        new Thread(()-> System.out.println("hello java8.0")).start();
    }

hello java8
hello java8.0

将代码逻辑当做参数传递给方法

 public static Integer getAge(Function<String, Integer> function, String args) {
        return function.apply(args);
    }
public static void main(String[] args) {
      
        System.out.println(getAge(a->Integer.parseInt(a),"112"));
    }
//112

复杂的需求根据不同颜色和重量获取数据

@Data
public class Apple {
    private Integer id;
    private String color;
    private Integer weight;
    private String origin;

    public Apple(Integer id, String color, Integer weight, String origin) {
        this.id = id;
        this.color = color;
        this.weight = weight;
        this.origin = origin;
    }
}

main

public List<Apple> getApplesByPredicates(Predicate<Apple> predicate) {
        ArrayList list = new ArrayList();
        for (Apple apple : apples) {
            if(predicate.test(apple)){
                list.add(apple);
            }
        }
//简单的stream表达式
//return apples.stream().filter(predicate).collect(Collectors.toList());
        return list;
    }

    public static void main(String[] args) {
        AppServer appServer = new AppServer();
        appServer.apples.add(new Apple(10,"red",200,"gz"));
        appServer.apples.add(new Apple(11,"green",201,"gzs"));
        appServer.apples.add(new Apple(13,"red",201,"gzd"));

         List<Apple> red = appServer.getApplesByPredicates(apple -> apple.getColor().equals("red")&&apple.getId()>10);

        for (Apple apple : red) {
            System.out.println("id:"+apple.getId());
            System.out.println("color:"+apple.getColor());
        }
    }

id:13
color:red

自定义函数式接口

@FunctionalInterface
public interface MyFunction {
    //加了@FunctionalInterface注解
    //接口中只有唯一的抽象方法,自动推导成函数式接口
    //如果多余的抽象方法是Object的方法,不印象第一条
    
    void  sayHello();
    @Override
    String toString();
    default void sayHello2(){};
}
1.1 三种编写方式
  • expression 单条语句表达式
  • statement 语句块
  • refrence 方法引用
1.2 expression 只能是一个语句

两个参数

@FunctionalInterface
public interface MyFunction {
    //加了@FunctionalInterface注解
    //接口中只有唯一的抽象方法,自动推导成函数式接口
    //如果多余的抽象方法是Object的方法,不印象第一条

    void  sayHello(String name,String content);
    @Override
    String toString();
    default void sayHello2(){};
}

main方法

MyFunction myFunction = ((name, content) -> System.out.println(name + content));
        myFunction.sayHello("张三,", "你好 java!");

//结果: 张三,你好 java!
1.3 statement 语句块,执行多个代码段
@FunctionalInterface
public interface MyFunction2 {
    //加了@FunctionalInterface注解
    //接口中只有唯一的抽象方法,自动推导成函数式接口
    //如果多余的抽象方法是Object的方法,不印象第一条

    String  sayHello(String name,String content);
    @Override
    String toString();
    default void sayHello2(){};
}

main方法

public static void main(String[] args) {
        MyFunction2 myFunction = ((name, content) -> {
            System.out.println(name);
            System.out.println(content);
            return name+content;
        });
        System.out.println(myFunction.sayHello("张三,", "你好 java!"));
    }

结果

张三,
你好 java!
张三,你好 java!
1.4 refrence 引用

实例方法引用

public class RefrenceTest {
    public String sayHello(String name) {
        System.out.println(name);
        return name + "say hi";
    }

    static void test1() {
        RefrenceTest test = new RefrenceTest();
        Function<String, String> f = test::sayHello;
        System.out.println(f.apply("李四"));
    }

    public static void main(String[] args) {
        test1();
    }
}


李四
李四say hi
1.5 老版本的Java中排列字符串
List<String> names = Arrays.asList("peter", "anna", "mike", "xenia");

Collections.sort(names, new Comparator<String>() {
    @Override
    public int compare(String a, String b) {
        return b.compareTo(a);
    }
});

只需要给静态方法 Collections.sort 传入一个List对象以及一个比较器来按指定顺序排列。通常做法都是创建一个匿名的比较器对象然后将其传递给sort方法。

1.6 Java 8提供了更简洁的语法,lambda表达式:
public class Lambda {
    List<String> names = Arrays.asList("peter", "anna", "mike", "xenia");
   public void test(){
       Collections.sort(names,(String a, String b)->{
           return b.compareTo(a);
       });
   }
}

2. Stream流

@Data
public class User {
    private String name;
    private int age;

    public User() {
    }

    public User(String name, int age) {
        this.name = name;
        this.age = age;
    }

}

数据

static List<User> list = Arrays.asList(
            // name,age
            new User("张三", 11),
            new User("王五", 20),
            new User("王五", 91),
            new User("张三", 8),
            new User("李四", 44),
            new User("李四", 44),
            new User("李四", 44)
    );
2.1 stream lambda
// java 8 stream lambda
         list.stream().forEach(user -> System.out.println(user));

User(name=张三, age=11)
User(name=王五, age=20)
User(name=王五, age=91)
User(name=张三, age=8)
User(name=李四, age=44)
User(name=李四, age=44)
User(name=李四, age=44)

2.2 sort
list.stream().sorted(Comparator.comparing(User::getAge)).forEach(System.out::println);

User(name=张三, age=8)
User(name=张三, age=11)
User(name=王五, age=20)
User(name=李四, age=44)
User(name=李四, age=44)
User(name=李四, age=44)
User(name=王五, age=91)

2.3 filter 输出年龄大于50的人
list.stream().filter(user -> user.getAge()>50).forEach(System.out::println);

User(name=王五, age=91)
2.4 limit():使用该方法截断
list.stream().limit(3).forEach(System.out::println);

User(name=张三, age=11)
User(name=王五, age=20)
User(name=王五, age=91)
2.5 skip():与limit互斥,使用该方法跳过元素
list.stream().skip(3).forEach(System.out::println);

User(name=张三, age=8)
User(name=李四, age=44)
User(name=李四, age=44)
User(name=李四, age=44)
2.6 distinct():使用该方法去重,注意:必须重写对应泛型的hashCode()和equals()方法
list.stream().distinct().forEach(System.out::println);

User(name=张三, age=11)
User(name=王五, age=20)
User(name=王五, age=91)
User(name=张三, age=8)
User(name=李四, age=44)
2.7 max,min,sum,avg,count
 IntSummaryStatistics num = list.stream().mapToInt(value -> value.getAge()).summaryStatistics();
        System.out.println("总共人数:" + num.getCount());
        System.out.println("平均年龄:" + num.getAverage());
        System.out.println("最大年龄:" + num.getMax());
        System.out.println("最小年龄:" + num.getMin());
        System.out.println("年龄之和:" + num.getSum());

总共人数:7
平均年龄:37.42857142857143
最大年龄:91
最小年龄:8
年龄之和:262
2.8 map():接收一个方法作为参数,该函数会被应用到每个元素上,并将其映射成一个新的元素
List<String> words = Arrays.asList("aaa", "vvvv", "cccc");
words.stream().map(s -> s.toUpperCase()).collect(Collectors.toList()).forEach(System.out::println);

AAA
VVVV
CCCC
2.9 reduce
//reduce 操作可以实现从一组元素中生成一个值
        //sum()、max()、min()、count()等都是reduce操作,将他们单独设为函数只是因为常用
        //例如:找到年龄最大的
        Optional<User> reduce1 = list.stream().reduce((user, user2) -> user.getAge() > user2.getAge() ? user : user2);
        System.out.println(reduce1.get());

User(name=王五, age=91)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值