Java jdk8版本特性(未完成版)

一、JDK8新特性

①引入Lambda表达式:

// 实现集合元素的遍历输出

List<String> names = Arrays.asList("peter", "anna", "mike", "xenia");



// 老版本实现

for(int i = 0 ; i < names.size() ; i++){
     system.out.println("姓名:" + names.get(i));
}

for(String name : names){
     system.out.println("姓名:" + name);
}




// JKD8 Lambda 实现

names.foreach({value}->system.out.println("姓名: " + value));


②引入函数式接口

函数式接口在Java中指:有且只有一个抽象方法的接口(接口中可以包含其他方法如:默认方法、静态方法、私有方法)

函数式接口的核心设计目的:为了完美适配 Lambda 表达式​(函数式接口有且只能有一个抽象方法,因此Lambda能够精准重写接口中的抽象方法)

@FunctionalInterface:

针对函数式接口 Java8 中引入了一种新注解----@FunctionalInterface 进行声明(编译器在编译时会对标注了该注解的接口进行判断,判断其是否只有一个抽象方法,如果多于一个或者少于一个则会报错)

函数式接口的使用:

// 定义一个函数式接口

@FunctionalInterface
public interface MyFunctionalInterface(){
  //具有 有且只有一个 抽象方法

  public abstract void method();

}


// 假设该接口有一个实现类

public class MyFunctionalInterfaceImpl implements MyFunctionalInterface{
   
    @Override
    public void method(){
     System.out.println(“实现类的method方法”)
    }

}


// 在对应测试类中有以下使用方式:

public class Demo {

  //定义一个方法,参数使用函数式接口 MyFunctionalInterface
 public static void show(MyFunctionalInterface myInter){
        myInter.method();
 }



public static void main(String[] args){

     //调用show方法,方法的参数是一个接口,所以可以传递该接口的实现类对象(多态)
     show(new MyFunctionalInterfaceImpl);


     //调用show方法,方法参数是一个接口,也可以直接传递该接口的匿名内部类
     show(new MyFunctionalInterface(){
          @Override
          public void method(){
             System.out.println("使用匿名内部类重写的method");
          }
     };

      

     //调用show方法,方法参数是一个接口,也可以直接用lambda表达式实现
     show( () -> { System.out.println("使用Lambda表达式重写接口中的method方法"); } )


 }

③增加方法和构造函数的引用

方法引用/构造函数引用:允许通过方法名直接引用已有方法,替代Lambda表达式

方法引用:

-- 引用方法

Convert<String, Integer> converter = Integer :: valueOf;  

//定义一个类型转换器 , 转换规则 -> Integer中的valueOf方法

Integer converted = converter.convert("123");

System.out.println(converted.getClass()); 

④提供了很多函数式接口

⑤引入了Streams流

Streams流:表示能应用在一组元素上一次执行的操作序列

Streams流操作分为中间操作+最终操作,最终操作返回特定类型的计算结果,中间操作返回Stream本身。

Streams流对集合常见操作:

收集(将流元素聚合到集合或者其他数据结构中):

方法:collect(Collector)

常用收集器:

Collectors.toList():收集为List集合

Collectors.toSet():收集为Set集合

Collectors.joining():拼接为字符串

Collectors.groupingBy():按条件分组 

--- 返回值为Map<P,T>类型  P为你分组的条件数据  T为按条件分类后的对应数据

例子:


List<String> names = Arrays.asList("Alice", "Bob", "Charlie");


//转化为Set集合
Set<String> nameSet = names.stream().collect(Collectors.toSet());

//按字符串长度分组
Map<Integer,List<String>> groupByLength = names
                          .stream()
                          .collect( 
                          Collectors.groupingBy(String::length));

// 按字符串长度分组:{3=[Bob], 5=[Alice], 7=[Charlie]}

Filter(过滤):

通过一个predicate接口来过滤并只保留符合条件的元素,该操作属于中间操作

-- Predicate<T> 函数式接口定义

@FunctionalInterface
public interface Predicate<T> {
    boolean test(T t);     //输入一个元素,返回布尔值
}



-- Stream接口的Filter方法定义

Stream<T> filter(Predicate<? super T> predicate);

List<User> users = Arrays.asList(
    new User("Alice", 28, "北京"),
    new User("Bob", 22, "上海"),
    new User("Charlie", 25, "北京")
);


// 过滤出年龄在25-30区间内的数据

List<User> filteredUsers = users.stream().filter(u -> u.getAge()>=25 && u.getAge() <= 30)
                                         .collect(Collectors.toList());


// 过滤出地址为北京的数据

List<User> filteredUsers = users.stream().filter(u -> u.getCity().equals("北京"))
                                         .collect(Collectors.toList());

// 过滤出姓名以B开头的用户

List<User> filteredUsers = users.stream().filter(u -> u.getUserName().startwith("B"))
                                         .collect(Collectors.toList());

Sorted(排序):

排序是一个中间操作,返回的是一个排序后的Stream,如果不指定一个自定义的 Comparator 则会使用默认排序。

-- Sort排序

stringList.stream().sorted().filter(s->s.startWith("a")).forEach(System,out::println);

需要注意的是,排序只创建了一个排列好后的 Stream,而不会影响原有的数据源,排序之后原数据 stringList 是不会被修改的。

Map(映射):

将元素根据指定的Function接口来依次将元素转换成另外的对象,map也是一个中间操作

-- 测试Map操作

stringList.stream().map(String::toUpperCase)       //将集合中所有数据转为大写
                   .sorted((a,b) -> b.compareTo(a))  //反转集合顺序
                   .forEach(System.out::println);    //迭代输出元素

Match(匹配):

Stream提供了多种匹配操作,允许监测指定的Predicate(同上文过滤)是否匹配整个Stream。所有的匹配操作都是最终操作,并返回一个boolean类型的值

-- 遍历流中的元素,对每个元素使用predicate.test(element)


// anyMatch

-- 如果存在至少一个元素使得方法返回true,则立即返回true并终止处理
-- 如果所有元素都不满足,返回false

boolean anyStartsWithA = stringList.stream()
                                   .anyMatch(s->s.startWith("a"));


// allMatch

-- 如果所有元素都能使方法返回true,则返回true
-- 如果存在一个元素都不满足,返回false

boolean allStartsWithA =stringList.stream()
                                  .allMatch((s) -> s.startsWith("a"));


// noneMatch

-- 如果存在元素使方法返回true,则返回false
-- 如果不存在元素能够返回true,返回true

boolean noneStartsWithZ = stringList.stream()
                                    .noneMatch((s) -> s.startsWith("z"));

Count(计数):

返回Stream中的元素个数,返回值类型为long,是一个最终操作

-- Count 计数操作

 long startsWithB = stringList.stream()
                              .filter((s) -> s.startsWith("b"))
                              .count();

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值