专题——java8新特性

java8新特性

【说明】:这里只列举了常用的新特性,还有方法引用,Nashorn JavaScript,Java8 Base64

  1. String类中添加join方法
  2. lambda表达式
  3. 函数式接口
  4. 接口中添加静态方法和默认方法
  5. Stream流
  6. Optional类
  7. 日期时间API

1. String中添加join方法

在这里插入图片描述

/**
 * java8新特性-String中添加join方法
 * 用于拼接字符串
 */
public class NewMehtod {
    public static void main(String[] args) {
        // 用-连接数字
        // 传递可变参数
        System.out.println(String.join("-", "1", "2", "3")); // 1-2-3

        // 传递数组
        String[] strArray = new String[]{"1", "2", "3"};
        System.out.println(String.join("-", strArray)); // 1-2-3

        // 传递实现Iterator接口的类
        List<String> list = new ArrayList<>();
        list.add("1");
        list.add("2");
        list.add("3");
        System.out.println(String.join("-", list)); // 1-2-3
    }
}

2.lambda表达式

/**
 * java8新特性-lambda表达式
 */
public class Lambda {
    public static void main(String[] args) {
        // 匿名内部类的方式
        Action action = new Action(new Flyable() {
            @Override
            public void fly() {
                System.out.println("普通方法飞行");
            }
        });
        action.start();

        // lambda方式
        Action action1 = new Action(()->System.out.println("lambda方式飞行"));
        action1.start();
    }
}

interface Flyable {
    void fly();
}

class Action {
    private Flyable flyable;

    public Flyable getFlyable() {
        return flyable;
    }

    public void setFlyable(Flyable flyable) {
        this.flyable = flyable;
    }

    public Action(Flyable flyable) {
        this.flyable = flyable;
    }

    public void start() {
        flyable.fly();
    }
}

lambda表达式中使用外部的局部变量默认是final的,不可以在重写方法中改变变量的值。

3.函数式接口

只有一个抽象方法


/**
 * java8新特性-函数式接口
 */
public class FunctionInterface {
    public static void main(String[] args) {
        List<Integer> list = new ArrayList<>();
        list.add(1);
        list.add(2);
        list.add(3);
        eval(list, new Predicate<Integer>() {
            @Override
            public boolean test(Integer integer) {
                return integer > 2;
            }
        });// 3

        eval(list,n->n>1);// 2 3
    }

    /**
     * 打印list中满足条件的数
     *
     * @param list
     * @param predicate 只有一个抽象方法的接口(函数式接口)
     */
    public static void eval(List<Integer> list, Predicate<Integer> predicate) {
        list.forEach(item -> {
            if (predicate.test(item)) {
                System.out.println(item + " ");
            }
        });
    }

}

【20220403补充】
函数式接口标识:@FunctionalInterface
1.三种类型:

    1. Supplier 供给型函数
@FunctionalInterface
public interface Supplier<T>{
	T get();
}
  • 2.Consumer 消费型函数
@FunctionalInterface
public interface Consumer<T>{
	void accept(T t);
}
  • 3.Runnable 无参无返回值型函数
@FunctionalInterface
public interface Runnable{
	void run();
}
  • 4.Function 有参有返回值型函数
@FunctionalInterface
public interface Function(T,R){
	R apply(T t);
}

2.工作中经常会遇见以下情况

  1. 处理抛出异常的if
  2. 处理if分支
  3. 存在值则执行消费操作,不存在执行值为空的操作

2.1 处理抛出异常的if
思想:将if语句和抛出异常封装到工具类和接口中

  1. 创建异常抛出接口
@FunctionalInterface
public interface ThrowExceptionFunction(){
	void throwException(String message);
}
  1. 创建工具类
public final class VUtils{
	private VUtils(){}
	public static ThrowException isTrue(boolean  b){
		return (message)->{
			if(b){
				throw new RuntimeException(message);
			}
		}
	}
}
  1. 使用
User user = null;
VUtils.isTrue(!Optional.ofNullable(user).isPresent()).throwException("用户信息不能为空")

2.2 处理if分支操作
思路和2.1一样,将if,else的操作分装到工具类中,执行的方法封装到函数式接口中
1.创建分支接口

	@FunctionalInterface
	public interface BranchHandleException{
		void trueOrFalseHandle(Runnable trueHandle,Runnable falseHandle);
	}
  1. 工具类中添加方法
	public static BranchHandleException isTrueOrFalse(boolean b){
		// 返回新创建的匿名内部类
		return (trueHandle,falseHandle)->{
			if(b){
				trueHandle.run();
			}else{
				falseHandle.run();
			}
		}
	}

3.使用

String str = "函数式接口真有趣";
VUtils.isTrueOrFalse(str.length()>0).trueOrFalseHandle(
	()->{
		System.out.println("字符串长度大于0");
	},()->{
	  System.out.println("字符串长度为0");
	}
	);

2.3存在值则执行消费操作,否则执行空的操作

  1. 创建值与非空值的分支处理接口
@FunctionalUbterface
public interface PresentOrElseHandler{
	void presentOrElseHandle(Consumer<? super T action,Runnable emptyAction);
}
  1. 在工具类中添加方法
public static presentOrElseHandler isBlankOrNotBlank(String str){
	return (consumer,runnable)->{
		if(StringUtils.isNotBlank(str)){
			consumer.accept(str);
		}else{
			runnable.run();
		}
	}
}
  1. 使用
String str = null;
VUtils.isBlankOrNotBlank(str).presentOrElseHandle(System.out::println,()->{
	System.out.println("空字符串");
})

4.接口中添加静态方法和默认方法

类可以重写接口中的抽象方法和默认方法,不能重写静态方法,如果重写静态方法,那么接口中的静态方法将会被隐藏

public class NewMethodInInterface {
    public static void main(String[] args) {
        TestClass testClass = new TestClass();
        testClass.abTest();// 重写抽象方法
        testClass.deTest();// 重写默认方法
        TestInterface.stTest();// 静态方法
    }
}
interface TestInterface{
    // 抽象方法
    void abTest();

    // 静态方法
    static void stTest(){
        System.out.println("静态方法");
    }

    // 默认方法
    default void deTest(){
        System.out.println("默认方法");
    }
}
class TestClass implements TestInterface{
    @Override
    public void abTest() {
        System.out.println("重写抽象方法");
    }

    @Override
    public void deTest() {
        System.out.println("重写默认方法");
    }
}

5.Stream流

对元素队列进行聚合操作

/**
 * java8新特性-Stream流
 */
public class StreamTest {
    public static void main(String[] args) {
        // forEach打印十个随机数 limit打印十条
        Random random = new Random();
        random.ints().limit(10).forEach(System.out::println);

        // map输出元素乘2后的结果 filter筛选出符合大于15的数字
        List<Integer> list = Arrays.asList(1, 34, 6, 5, 7, 8);
        list.stream().map(i -> i * 2).filter(i -> i > 10).forEach(i-> System.out.println(i));

        // sortd进行排序
        List<Integer> list1 = Arrays.asList(4, 3, 6, 7, 2, 3, 9);
        list1.stream().sorted().forEach(i-> System.out.println(i));

        // Collectors返回列表或字符串
        List<String> list2 = Arrays.asList("23", "fd", "e5r");
        String tr = list2.stream().collect(Collectors.joining("tr"));
        String tr1 = String.join("tr", list2);
        System.out.println(tr);
        System.out.println(tr1);

    }
}

6.Optional类

用于判空,防止空指针异常

/**
 * java8新特性-Option类
 * 判空,获取值等操作,有效防止空指针异常
 */
public class OptionalTest {
    public static void main(String[] args) {
        List<Integer> list = Arrays.asList(1, 2, 5, 7, 6);
        List<Integer> nullList = null;

        // 会抛出空指针异常
//        Optional<List<Integer>> nullOption = Optional.of(nullList);

        // 不会抛出控制针异常
        Optional<List<Integer>> option = Optional.ofNullable(nullList);
        Optional<List<Integer>> list1 = Optional.ofNullable(list);
        // 判断是否为null
        if(list1.isPresent()){
            // toString  方法一般用来调试
            System.out.println(list1.toString());// Optional[[1, 2, 5, 7, 6]]

            // get 获取值
            List<Integer> list2 = list1.get();
            list2.forEach(System.out::print); // 12576
            System.out.println();
        }

        // 如果为null使用orElse获取 如果不为空则返回值,否则返回设定值
        List<Integer> list3 = list1.orElse(Arrays.asList(8, 7));// 12576
        List<Integer> list4 = option.orElse(Arrays.asList(8, 7));// 87
        list3.forEach(System.out::print);
        System.out.println();
        list4.forEach(System.out::print);
    }
}

7.日期时间API

java7中java.util.Date和java.util.Calendar易用性差,不支持时区,并且是可变的,意味着他们是不安全的

  • Instant:瞬时实例
  • LocalDate:本地日期
  • LocalTime:本地时间
  • LocalDateTime:组合了日期和时间
  • ZoneDateTime:最完整的日期时间
  • ZoneOffSet和ZoneId:解决了时区问题
  • DateTimeFormatter:日期和字符串之间转换
/**
 * java8新特性-日期时间API
 */
public class DateTimeTest {
    public static void main(String[] args) {
        // 获取当前日期时间
        LocalDateTime now = LocalDateTime.now();
        System.out.println(now);// 2022-02-18T23:15:36.698

        // 获取当前时间绝对秒
        Instant instant = now.atZone(ZoneId.systemDefault()).toInstant();
        long epochSecond = instant.getEpochSecond();
        System.out.println(epochSecond);// 1645197336

        // 获取当前日期
        LocalDate localDate = now.toLocalDate();
        System.out.println(localDate);// 2022-02-18

        // 获取当前时间
        LocalTime localTime = now.toLocalTime();
        System.out.println(localTime);// 23:15:36.698

        // 日期与字符串相互转换
        // 日期转字符串
        String pattern = "yyyy-MM-dd";
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(pattern);
        String format1 = now.format(dateTimeFormatter);
        System.out.println(format1);// 2022-02-18

        // 字符串转日期
        String datetimeText = "1965-02-12";
        LocalDate parse = LocalDate.parse(datetimeText,dateTimeFormatter);
        System.out.println(parse);// 1965-02-12
    }
}
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值