Java 7、Java 8常用新特性

        MyInterfaceImpl myInterface = new MyInterfaceImpl();
        myInterface.abstractMethod();
        myInterface.defaultMethod();

        MyInterface.staticMethod();


4、函数式接口

在Java 8中,函数式接口(Functional Interface)是一个只有一个抽象方法的接口。由于Lambda表达式的引入,函数式接口变得特别有用,因为Lambda表达式可以被用来简洁地表示这些接口的实现。函数式接口是Java实现函数式编程特性的基础。

4.1 自定义函数式接口

Lambda 表达式经常与函数式接口一起使用。定义一个无实现类的接口,接口方法有且只有一个。

@FunctionalInterface
public interface MyService {
    void myMethod(String l);
}

MyService myService=(s)-> System.out.println(s);
//或
MyService myService=(s)-> {
	System.out.println(s);
};

myService.myMethod("这是一个自定义的函数式接口");


/\* 等价写法 \*/
public interface MyService {
	void myMethod(String l);
}

public class MyServiceImpl implements MyService {
    @Override
    public void myMethod(String l) {
        System.out.println(l);
    }	
}

myService.myMethod("这是一个字符串");

4.2 内置函数式接口

Java 8 中添加了很多内置的函数式接口,比如 Runnable, Callable, Comparator, Predicate 等,路径在java.util.function包中。
在这里插入图片描述


类型参数定义及示例:

  • < T > 参数输入类型
  • < U > 第二个参数输入类型
  • < R > 参数输出类型

Predicate< T > 接口

        Predicate<Integer> predicate = s -> s>6;
        boolean result = predicate.test(7); // true
        System.out.println(result);


Function<T, R>接口

        Function<Integer, Integer> function = s -> s \* s;
        Integer result = function.apply(6); // 36
        System.out.println(result);


BiFunction<T, U, R> 接口

        BiFunction<Integer,Integer,String> biFunction = (x,y)->{
            Integer z=x\*y;
          return "计算结果为:"+z;
        };
        String result =biFunction.apply(3,6);
        System.out.println(result); // 计算结果为:18


5、Date/Time API

Java 8引入了全新的Date/Time API,它提供了更简洁、易读和强大的日期时间处理能力。这个新的API是线程安全的,并且是不可变的,这意味着每次对日期时间的修改都会返回一个新的对象,而原始对象则保持不变,路径在java.time包中。以下是Java 8 Date/Time API的一些主要类和接口:

方法说明默认输出格式
LocalDate表示没有时区的日期2024-03-27
LocalTime表示没有时区的时间17:00:23.741
LocalDateTime表示包含日期和时间的日期时间,没有时区2024-03-27T17:00:23.741
ZonedDateTime表示包含日期、时间、时区的日期时间2024-03-27T17:00:23.742+08:00[GMT+08:00]
OffsetTime表示带有时区偏移的时间17:00:23.742+08:00
OffsetDateTime表示带有时区偏移的日期时间2024-03-27T17:00:23.743+08:00
Period表示年、月、日之间的时间段P2024Y1M1D
Duration表示时间量,通常以秒和纳秒为单位PT60H
TemporalAdjuster用于调整日期和时间的接口/
ChronoUnit枚举类型,表示时间单位,如天、小时、分钟等/
ZoneId表示时区ID的类/
ZoneOffset表示时区偏移的类/
DateTimeFormatter格式化日期时间/

一些常用方法示例:

        //表示没有时区的日期
        LocalDate localDate1 =LocalDate.now();
        LocalDate localDate2 =LocalDate.of(2024, 1,1);
        System.out.println(
                "当前日期:"+localDate1.toString()+"\n"+
                "设置规定日期:"+localDate2.toString()
        );


        //格式化日期
        DateTimeFormatter dateTimeFormatter1 =DateTimeFormatter.ofPattern("yyyy/MM/dd");
        String format1 = localDate1.format(dateTimeFormatter1);
        String format2 = localDate1.format(DateTimeFormatter.ISO\_DATE);
        System.out.println(
                "自定义日期格式:"+format1+"\n"+
                "内置日期格式:"+format2
        );

        //解析字符串为日期
        LocalDate parse1 = LocalDate.parse("2024-01-01");
        LocalTime parse2 = LocalTime.parse("12:00:00",DateTimeFormatter.ISO\_TIME);
        System.out.println(parse1+"\n"+parse2);


        //表示没有时区的时间
        LocalTime localTime1 =LocalTime.now();
        LocalTime localTime2 =LocalTime.of(10,0,0);
        System.out.println(
                "当前时间:"+localTime1.toString()+"\n"+
                "设置规定时间:"+localTime2.toString()
        );

        //格式化时间
        DateTimeFormatter dateTimeFormatter2 =DateTimeFormatter.ofPattern("HH点mm分ss秒");
        String format3 = localTime1.format(dateTimeFormatter2);
        String format4 = localTime1.format(DateTimeFormatter.ISO\_TIME);
        System.out.println(
                "自定义时间格式:"+format3+"\n"+
                "内置时间格式:"+format4
        );


        //表示包含日期和时间的日期时间,没有时区
        LocalDateTime localDateTime = LocalDateTime.now();
        System.out.println(localDateTime);

        //格式化时间日期
        DateTimeFormatter dateTimeFormatter3 =DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss");
        String format5 = localDateTime.format(dateTimeFormatter3);
        String format6 = localDateTime.format(DateTimeFormatter.ISO\_LOCAL\_DATE\_TIME);
        System.out.println(
                "自定义时间日期格式:"+format5+"\n"+
                "内置时间日期格式:"+format6
        );

        //表示包含日期、时间、时区的日期时间
        ZonedDateTime zonedDateTime =ZonedDateTime.now();
        System.out.println(zonedDateTime);

        //表示带有时区偏移的时间
        OffsetTime offsetTime =OffsetTime.now();
        System.out.println(offsetTime);

        //表示带有时区偏移的日期时间
        OffsetDateTime offsetDateTime =OffsetDateTime.now();
        System.out.println(offsetDateTime);

        //表示年、月、日之间的时间段
        Period period =Period.of(2024,1,1);
        System.out.println(period.toString());

        //表示时间量,通常以秒和纳秒为单位
        Duration duration=Duration.of(60, ChronoUnit.HOURS);
        System.out.println(duration);

        //用于调整日期和时间的接口
        TemporalAdjuster temporalAdjuster =(s)->{
            return s;
        };
        LocalDate localDate = localDate1.plusDays(1);
        Temporal temporal = temporalAdjuster.adjustInto(localDate);
        System.out.println(temporal.toString());

        //枚举类型,表示时间单位,如天、小时、分钟等
        ChronoUnit chronoUnit=ChronoUnit.DAYS;
        System.out.println(chronoUnit.toString());

        //表示时区ID的类
        ZoneId zoneId=ZoneId.of("GMT+08:00");
        System.out.println(zoneId.toString());

        //表示时区偏移的类
        ZoneOffset zoneOffset =ZoneOffset.of("+08:00");
        System.out.println(zoneOffset.toString());


6、Optional 容器类型

Optional 是 Java 8 引入的一个容器对象,用于表示某个值存在或不存在,而不是传统的 null 值。Optional 提供了一种更优雅和类型安全的方式来处理可能为 null 的值,从而避免了 NullPointerException。当你有一个值可能是 null,并且你想以更清晰、更简洁的方式处理这种情况时,Optional 就非常有用。使用 Optional 可以使你的代码更易于阅读和维护,同时减少处理 null 值时的错误。

/\* 示例 \*/
        // 使用 of 方法创建一个包含值的 Optional
        Optional<String> optional1 = Optional.of("hello world");

        // 使用 ofNullable 方法创建一个可能包含 null 的 Optional
        Optional<String> optional2 = Optional.ofNullable(null);

        // 创建一个空的 Optional
        Optional<String> optional3 = Optional.empty();

        System.out.println(
                "optional1的值:"+optional1+"\n"+
                "optional2的值:"+optional2+"\n"+
                "optional3的值:"+optional3
        );

		/\* 常用方法 \*/
		// isPresent() 检查值是否存在
        boolean present = optional1.isPresent(); //true
        System.out.println(present);

        // ifPresent() 如果值存在则执行给定的操作
        optional1.ifPresent(s->{
            System.out.println("打印:"+s); //打印:hello world
        });

        // get() 获取值,如果 Optional 为空则抛出 NoSuchElementException
        String s1 = optional1.get();

        // orElse() 如果值存在则返回它,否则返回提供的默认值
        String s2 = optional2.orElse("optional2值为空");

        // orElseGet() 如果值存在则返回它,否则使用提供的 Supplier 生成默认值
        String s3 = optional3.orElseGet(() -> {
            return "optional3值为空";
        });

        System.out.println(
                "s1:"+s1+"\n"+
                "s2:"+s2+"\n"+
                "s3:"+s3
        );

        // map() 如果值存在则应用函数并返回新的 Optional,不存在则不执行map()
        Optional<Integer> optional4 = optional1.map(String::length);
        Optional<Integer> optional5 = optional2.map(String::length);
        System.out.println(
                "optional4:"+optional4.orElse(-1)+"\n"+
                "optional5:"+optional5.orElse(-1)
        );

        // flatMap() 如果值存在则应用函数并返回结果的 Optional,否则返回空的 Optional
        Optional<String> optional6 = optional1.flatMap(s -> {
            return Optional.ofNullable("获取optional1的值:" + s);
        });
        Optional<String> optional7 = optional2.flatMap(s -> {
            return Optional.ofNullable("获取optional2的值:" + s);
        });
        System.out.println(
                "optional6:"+optional6.orElse(null)+"\n"+
                "optional7:"+optional7.orElse(null)
        );


7、Stream API

7.1 Streams流

在Java 8及更高版本中,Stream API 提供了一种新的、函数式的方法来处理集合(如 List、Set 等)。使用 Stream API,你可以轻松地对集合进行各种操作,如过滤、映射、排序、聚合等,而无需显式地编写循环。

方法简要说明
forEach(Consumer action)遍历元素,执行指定的操作
peek(Consumer action)遍历元素,插入节点调试,不影响原本操作
distinct()去除重复元素
sorted()升序排序
count()计数
filter(Predicate predicate)过滤出所有符合条件的元素 相当于if
map(Function mapper)将元素转换为特定类型
flatMap(Function mapper)嵌套map
IntStream.sum()聚合元素
boxed()将基本数据类型转换为对应的包装类类型
limit(long maxSize)限制元素数量,设定集合容量
skip(long n)跳过前N个元素
findFirst()返回第一个元素
findAny()返回任意一个元素
reduce(BinaryOperator accumulator)将所有元素归成一个约定的结果
collect(Collector collector)收集结果到一个集合中
allMatch(Predicate predicate)判断是否所有元素符合给定条件
anyMatch(Predicate predicate)判断是否有元素符合给定条件
noneMatch(Predicate predicate)判断是否所有元素都不符合给定条件
/\* 示例 \*/
        // forEach 遍历元素,执行指定的操作
        List<String> list1 = Arrays.asList("a", "b", "c");
        list1.stream().forEach(s-> System.out.println(s));
        list1.stream().forEach(System.out::println);

        //peek 遍历元素,插入节点调试,不影响原本操作
        List<Integer> list = Arrays.asList(1,2,3,4,5);
        List<Integer> collect = list.stream()
                .filter(s->s>2)
                .peek(s -> System.out.println("输出:"+s))
                .collect(Collectors.toList());

        // distinct 去除重复元素
        List<Integer> list2 = Arrays.asList(1, 2, 1, 3);
        List<Integer> collect2 = list2.stream().distinct().collect(Collectors.toList());
        System.out.println(collect2);

        // sorted 升序排序
        List<String> list3 = Arrays.asList("a", "l", "c","j");
        List<String> collect3 = list3.stream().sorted().collect(Collectors.toList());
        System.out.println(collect3);

        // count 计数
        long count = list3.stream().count();
        System.out.println(count);

        // filter 过滤出所有符合条件的元素 相当于if
        List<Integer> list4 = Arrays.asList(9, 8, 7, 6);
        List<Integer> collect4 = list4.stream().filter(s -> s > 6).collect(Collectors.toList());
        System.out.println(collect4);

        // map 将元素转换为特定类型
        List<Integer> list5 = Arrays.asList(1,2,3,4,5);
        List<String> collect5 = list5.stream().map(s -> {
            return "计算结果为:"+s\*s;
        }).collect(Collectors.toList());
        System.out.println(collect5);

        // flatMap 嵌套map
        List<Integer> collect6 = list5.stream().flatMap(s -> {
            return list5.stream().filter(a -> a > 4);
        }).collect(Collectors.toList());
        System.out.println(collect6);

        //sum 聚合元素
        int sum = list5.stream().mapToInt(s -> s \* 2).sum();
        System.out.println("sum:" + sum);

        // boxed 将基本数据类型转换为对应的包装类类型
        int [] a ={1,2,3,4,5};
        List<Integer> collect7 = Arrays.stream(a).boxed().collect(Collectors.toList());
        System.out.println(collect7);

        List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
        IntStream intStream = numbers.stream().mapToInt(i -> i);  //转成IntStream
        Stream<Integer> boxed = intStream.boxed();                //转成Stream<Integer>
        List<Integer> collect8 = boxed.collect(Collectors.toList());
        System.out.println(collect8);


        //limit 限制元素数量,设定集合容量
        List<Integer> list9 = Arrays.asList(1,2,3,4,5);
        List<Integer> collect9 = list9.stream().limit(2).collect(Collectors.toList());
        System.out.println(collect9);

        //skip 跳过前N个元素
        List<Integer> list10 = Arrays.asList(1,2,3,4,5);
        List<Integer> collect10 = list10.stream().skip(3).collect(Collectors.toList());
        System.out.println(collect10);

        //findFirst() 返回第一个元素,findAny() 返回任意一个元素
        List<Integer> list11 = Arrays.asList(1,2,3,4,5);
        Optional<Integer> first = list11.stream().findFirst();
        Optional<Integer> any = list11.stream().findAny();
        System.out.println(
                "返回第一个元素:"+first.toString()+"\n"+
                "返回任意一个元素:"+any.toString()
        );


        /\* 将所有元素归成一个约定的结果 \*/
        List<Integer> list1 = Arrays.asList(1,2,3,4,5);
        Integer reduce1 = list1.stream().reduce(0, (x, y) -> x + y);
        System.out.println(reduce1);

        List<String > list2 = Arrays.asList("a","b","c");
        Optional<String> reduce2 = list2.stream().reduce((x, y) -> x + y);
        System.out.println(reduce2.toString());

        List<Integer> list3 = Arrays.asList(1,2,3,4,5);
        BinaryOperator<Integer> binaryOperator = (x, y)->x\*y;
        Integer reduce3 = list3.stream().reduce(1,binaryOperator, binaryOperator);
        System.out.println(reduce3);

        List<Integer> list = Arrays.asList(1,2,3,4,5);

        //allMatch 判断是否所有元素符合给定条件
        Predicate<Integer> predicate1 = s -> s>0;
        boolean b1 = list.stream().allMatch(predicate1);
        System.out.println("判断是否所有元素符合给定条件: "+b1);

        //anyMatch 判断是否有元素符合给定条件
        Predicate<Integer> predicate2 = s -> s>4;
        boolean b2 = list.stream().anyMatch(predicate2);
        System.out.println("判断是否有元素符合给定条件: "+b2);

        //noneMatch 判断是否所有元素都不符合给定条件
        Predicate<Integer> predicate3 = s -> s>10;
        boolean b3 = list.stream().noneMatch(predicate3);
        System.out.println("判断是否所有元素都不符合给定条件: "+b3);

7.2 Collectors收集器

在Java 8中,Collectors是一个静态工具类,它提供了许多有用的收集器(Collector)实现,用于支持在流(Stream)上的各种聚合操作。这些收集器可以用于收集流中的元素,并生成一个汇总结果或一个汇总结果的集合。以下是一些常用的Collectors收集器方法:

方法简要说明
toList()将流中的元素收集到一个List中
toSet()将流中的元素收集到一个Set中,去除重复项
toCollection(Supplier collectionFactory)将流中的元素收集到指定的集合类型中
toMap(Function keyMapper,Function valueMapper,BinaryOperator mergeFunction)将流中的元素收集到一个Map中
counting()计算流中元素的数量
summingInt(ToIntFunction mapper)对流中元素的某个属性进行求和,针对不同类型有不同方法,如:summingDouble,summingLong
averagingInt(ToIntFunction mapper)计算流中元素的某个属性的平均值,针对不同类型有不同方法,如:averagingDouble,averagingLong
maxBy(Comparator comparator)根据指定比较器找到流中最大的元素
minBy(Comparator comparator)根据指定比较器找到流中最小的元素
joining(CharSequence delimiter)将流中的元素连接成一个字符串,可以使用指定的分隔符
groupingBy(Function classifier)根据分类函数对流中的元素进行分组
reducing(BinaryOperator op)对流中的元素进行规定约定的操作
mapping(Function mapper,Collector downstream)对流中的元素应用映射函数,并对结果进行收集
collectingAndThen(Collector downstream,Function finisher)包裹另一个收集器,对其结果进行二次处理
/\* 示例 \*/
        //toList 将流中的元素收集到一个List中
        List<Integer> list1 = Arrays.asList(1,2,3,4,5);
        List<Integer> collect1 = list1.stream()
                .filter(s->s>3)
                .collect(Collectors.toList());
        System.out.println(collect1);

        //toSet 将流中的元素收集到一个Set中,去除重复项
        List<Integer> list2 = Arrays.asList(1,2,3,4,5,3);
        Set<Integer> collect2 = list2.stream().collect(Collectors.toSet());
        System.out.println(collect2);

        //toCollection 将流中的元素收集到指定的集合类型中
        List<Integer> list3 = Arrays.asList(1,2,3,4,5,3);
        HashSet<Integer> collect3 = list3.stream().collect(Collectors.toCollection(HashSet::new));
        System.out.println(collect3);

        //toMap 将流中的元素收集到一个Map中
        List<Person> list4 = Arrays.asList(
                new Person("L", 1, 18),
                new Person("J", 2, 18),
                new Person("A", 1, 30),
                new Person("A", 1, 20)
        );

        //key不鞥重复,针对有重复的情况需要处理 ------ (t,u)->u:当两个key相同时怎么处理
        Map<String, Integer> collect4 = list4.stream()
                .collect(Collectors.toMap(Person::getName, Person::getAge, (t, u) -> u));
        System.out.println(collect4);

        //counting 计算流中元素的数量
        List<Integer> list5 = Arrays.asList(1,2,3,4,5);
        Long collect5 = list5.stream().collect(Collectors.counting());
        System.out.println(collect5);

        //summingInt 对流中元素的某个属性进行求和,针对不同类型有不同方法,如:summingDouble,summingLong
        List<Integer> list6 = Arrays.asList(1,2,3,4,5);
        Integer collect6 = list6.stream().collect(Collectors.summingInt(Integer::intValue));
        System.out.println(collect6);

        //averagingInt 计算流中元素的某个属性的平均值,针对不同类型有不同方法,如:averagingDouble,averagingLong
        List<Integer> list7 = Arrays.asList(1,2,3,4,5);
        Double collect7 = list7.stream().collect(Collectors.averagingInt(Integer::intValue));
        System.out.println(collect7);

        //maxBy 根据指定比较器找到流中最大的元素
        List<Integer> list8 = Arrays.asList(1,2,3,4,5);
        Optional<Integer> collect8 = list8.stream()
                .collect(Collectors.maxBy(Comparator.comparingInt(Integer::intValue)));
        System.out.println(collect8.get());

        //minBy 根据指定比较器找到流中最小的元素
        List<Integer> list9 = Arrays.asList(1,2,3,4,5);
        Optional<Integer> collect9 = list9.stream()
                .collect(Collectors.minBy(Comparator.comparingInt(Integer::intValue)));
        System.out.println(collect9.get());

        //joining 将流中的元素连接成一个字符串,可以使用指定的分隔符
        List<String> list10 = Arrays.asList("a","b","c");
        String collect10 = list10.stream().collect(Collectors.joining("/"));
        System.out.println(collect10);

        //groupingBy 根据分类函数对流中的元素进行分组
        List<Person> list11 = Arrays.asList(
                new Person("L", 1, 18),
                new Person("J", 2, 18),
                new Person("A", 1, 30)
        );
        Map<Integer, List<Person>> collect11 = list11.stream()
                .collect(Collectors.groupingBy(Person::getSex));
        System.out.println(collect11);

        //reducing 对流中的元素进行规定约定的操作
        List<Integer> list12 = Arrays.asList(1,2,3,4,5);
        Optional<Integer> collect12 = list12.stream().collect(Collectors.reducing(Integer::sum));
        System.out.println(collect12.get());
        BinaryOperator<Integer> binaryOperator12=(x,y)->x+y;
        Optional<Integer> collect13 = list12.stream().collect(Collectors.reducing(binaryOperator12));
        System.out.println(collect13.get());

        //mapping 对流中的元素应用映射函数,并对结果进行收集
        List<Integer> list14 = Arrays.asList(1,2,3,4,5);
        List<String> collect14 = list14.stream()
                .collect(Collectors.mapping(String::valueOf, Collectors.toList()));
        System.out.println(collect14);

        Function<Integer,Integer> function15 =(s)->s\*s;
        List<Integer> collect15 = list14.stream()
                .collect(Collectors.mapping(function15, Collectors.toList()));
        System.out.println(collect15);

        //collectingAndThen 包裹另一个收集器,对其结果进行二次处理
        List<Integer> list16 = Arrays.asList(1,2,3,4,5);
        Function<Integer,String> function16 =(s)->{
            int l =s\*s;
            return "计算它的平方:" + l;
        };
        String collect16 = list16.stream()
                .collect(Collectors.collectingAndThen(Collectors.summingInt(Integer::intValue), function16));
        System.out.println(collect16);


7.3 Parallel Streams(扩展)

Java中的Parallel Streams是Java 8引入的一个新特性,它允许你以并行的方式处理数据集合,从而充分利用多核处理器的优势来提高程序的执行效率。通过使用Parallel Streams,你可以将原本顺序执行的任务分解成多个子任务,并在多个线程上同时执行这些子任务,从而加速数据的处理速度。

//示例
        List<Long> list = new ArrayList<>();
        for (long i = 1; i <=1\_000\_000 ; i++) {
            list.add(i);
        }

        long start1 = System.currentTimeMillis();
        List<Long> collect1 = list.stream()
                .map(s -> s \* s)
                .collect(Collectors.toList());
        long end1 = System.currentTimeMillis();
        System.out.println(new StringBuffer().append(end1-start1).append("ms"));

        long start2 = System.currentTimeMillis();
        List<Long> collect2 = list.parallelStream()
                .map(s -> s \* s)
                .collect(Collectors.toList());
        long end2 = System.currentTimeMillis();
        System.out.println(new StringBuffer().append(end2-start2).append("ms"));

使用并行流(parallel stream)需要注意:

确保你的任务是可以并行化的,即任务之间没有依赖关系,可以独立执行。

对于大规模数据集,使用并行流可以提高性能。但对于小数据集,顺序流可能更加高效。

避免在并行流中使用阻塞操作,这可能会导致线程阻塞和性能下降。

在使用并行流时,要注意线程安全问题,确保你的代码是线程安全的。


Java 7 常用新特性(补充)

1、二进制字面量

在Java 7中,引入了对二进制字面量的支持。二进制字面量以0b或0B开头,后跟一系列的0和1。

/\* 示例 \*/
        int i =0b11111111;
        int j =0B00000010;
        System.out.println("i: "+i+"\n"+"j: "+j); //i: 255 j: 2


2、数字字面量下划线支持

在Java 7中,引入了对数字字面量下划线的支持。这个特性允许在数字字面量中添加下划线(_)作为分隔符,以提高数字的可读性。这对于表示非常大的数字或者需要分组显示的数字特别有用。这个特性不会影响数字的值,下划线只是作为视觉上的分隔符。下划线可以出现在数字字面量的任何位置,除了数字的首位和末位,以及小数点的前面和后面。这个特性只适用于整数和浮点数的字面量,不适用于十六进制或八进制字面量。此外,虽然下划线可以提高代码的可读性,但过度使用可能会使代码变得难以阅读,因此建议适度使用。

/\* 示例 \*/
        int i=1\_000\_000;
        double r =3.14\_1\_5\_92\_7;
        long l=7\_7\_7\_7L;
        System.out.println(i); //1000000
        System.out.println(r); //3.1415927
        System.out.println(l); //7777


3、switch中使用String

在Java 7之前,switch语句仅支持字节型(byte)、短整型(short)、整型(int)、字符型(char)、枚举(enum)以及从Java 5开始引入的字符串类型(String)。然而,在Java 7中,对于switch语句中使用String类型的支持得到了扩展,允许你在switch语句中直接使用字符串。switch语句对字符串的比较是区分大小写的,switch语句中字符串的比较是通过字符串的equals方法进行的。

/\* 示例 \*/
        String a ="List";
        switch (a){
            case "list":
                System.out.println("list");
                break;
            case "List":
                System.out.println("List");
                break;
            case "set":
                System.out.println("set");
                break;
            default:
                System.out.println("default");
        }


4、对集合类的语言支持

Java 7 对集合类(Collections)的语言支持主要体现在对泛型实例创建的简化以及"diamond"操作符的引入,它减少了泛型代码中的冗余和错误。

4.1 泛型实例创建的简化

在Java 7之前,当创建一个泛型集合时,通常需要为集合和它的元素类型都指定泛型参数。Java 7中,对于类型推断的改进使得这种指定变得不必要,因为编译器可以根据上下文自动推断类型。

/\* 示例 \*/
        //Java 7之前写法
        List<String> list1 = new ArrayList<String>();
        
        //Java 7及以后的版本
        List<String> list2 = new ArrayList<>();

4.2 "diamond"操作符

"diamond"操作符在其他泛型上下文中得到应用,如方法返回类型、方法参数、构造函数参数等。它使得泛型代码更加简洁,减少了重复的类型参数声明。

/\* 示例 \*/
        //Java 7之前写法
        List<String> list1 = Arrays.asList(new String[]{"a", "b", "c"});

        //Java 7及以后的版本
        List<String> list2 = Arrays.asList("a", "b", "c");

/\* asList 源码 \*/
	
	// <T>:表示数组中对象的类,编译器可通过上下文自动推断类型
    public static <T> List<T> asList(T... a) {
        return new ArrayList<>(a);
    }


5、自动资源管理

在Java 7中,为了更方便地管理资源(如文件流、数据库连接、网络连接等),引入了自动资源管理(Automatic Resource Management)的概念,这个特性允许开发者在try语句块中声明一个或多个资源,这些资源在try语句块执行完毕后会自动关闭。这避免了手动关闭资源的繁琐操作,并减少了因忘记关闭资源而导致的资源泄露问题。要使用这个特性,资源类必须实现AutoCloseable接口或Closeable接口(Closeable接口是AutoCloseable接口的子接口)。

/\* 示例 \*/
	try (BufferedReader br = new BufferedReader(new FileReader("file.txt"))) {
	    String line;
	    while ((line = br.readLine()) != null) {
	        System.out.println(line);
	    }
	} catch (IOException e) {
	    e.printStackTrace();
	}

在上面的代码中,BufferedReader实现了Closeable接口,因此在try语句块执行完毕后,BufferedReader会自动关闭,无需手动调用br.close()。

6、try-catch多异常捕获

在Java 7及以后的版本中,try-catch语句块支持捕获多个异常类型,这是通过在一个catch块中指定多个异常类型来实现的,这些类型之间用竖线(|)分隔。这种语法允许你在一个catch块中处理多个不同类型的异常,而无需为每个异常类型编写单独的catch块。

/\* 示例 \*/
        //当try块中的代码抛出异常时,Java虚拟机(JVM)会检查catch块中列出的异常类型,并找到第一个与抛出的异常类型匹配的catch块。
        try {
            int i =1/0; // class java.lang.ArithmeticException

            String s =null; //class java.lang.NullPointerException
            s.indexOf(0);
        }catch (ArithmeticException | NullPointerException e){
            System.out.println("程序报错:"+e.getClass());
        }


7、文件流

在Java 7中,文件流(File Streams)的处理得到了显著改进,特别是通过引入java.nio.file包中的新API。这些新API提供了更简洁、更直观的方式来处理文件I/O操作,同时提供了对文件属性、文件访问权限以及异步文件I/O的更全面支持。

7.1 文件路径(Path)

java.nio.file.Path接口是文件路径的抽象表示。它提供了许多方法来操作路径,如解析、组合、规范化等。Paths类是一个工具类,提供了静态方法来创建Path对象。

/\* 示例 \*/
        Path path = Paths.get("C:\\Users\\777\\Desktop","MyPaths.txt");
        System.out.println(path); //C:\Users\777\Desktop\MyPaths.txt

7.2 文件属性(FileAttribute)

Java 7引入了FileAttribute接口,它允许你获取和设置文件的各种属性,如创建时间、最后访问时间、文件类型等。

/\* 示例 \*/
        Path path = Paths.get("D:\\File","MyPaths.txt");
        System.out.println(path);

        BasicFileAttributes basicFileAttributes = Files.readAttributes(path, BasicFileAttributes.class);
        System.out.println(
                "文件创建时间:"+basicFileAttributes.creationTime()+"\n"+
                "文件大小"+basicFileAttributes.size()
        );

7.3 文件I/O

java.nio.file包中的Files类提供了一组静态方法,用于简化文件I/O操作。以下是一些常见方法:

检查文件路径是否存在
/\* 示例 \*/
        Path path = Paths.get("D:\\File","MyPaths.txt");
        try{
            //检查文件路径是否存在
            boolean exists = Files.exists(path);
            System.out.println(exists);
        }catch (IOException e){
            System.out.println(e.getClass());
            e.printStackTrace();
        }

 **自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。**

**深知大多数Python工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!**

**因此收集整理了一份《2024年Python开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。**

![img](https://img-blog.csdnimg.cn/img_convert/ed66e8230fa3d7e9ecbadb8882cd1d50.png)

![img](https://img-blog.csdnimg.cn/img_convert/67aa744966ceeea3adbb28406242d6d5.png)

![img](https://img-blog.csdnimg.cn/img_convert/2c3c96327ca3dd49626291564cc31e0b.png)

![img](https://img-blog.csdnimg.cn/img_convert/20508b566092a9adccc0a7a0d7ea11c0.png)

![img](https://img-blog.csdnimg.cn/img_convert/6c361282296f86381401c05e862fe4e9.png)

![img](https://img-blog.csdnimg.cn/img_convert/9f49b566129f47b8a67243c1008edf79.png)

**既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上前端开发知识点,真正体系化!**

**由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新**

**如果你觉得这些内容对你有帮助,可以扫码获取!!!(备注Python)**

es.exists(path);
            System.out.println(exists);
        }catch (IOException e){
            System.out.println(e.getClass());
            e.printStackTrace();
        }

 **自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。**

**深知大多数Python工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!**

**因此收集整理了一份《2024年Python开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。**

[外链图片转存中...(img-awnbwDDa-1712872878005)]

[外链图片转存中...(img-FrJ1CyJH-1712872878006)]

[外链图片转存中...(img-bEOaNPBi-1712872878006)]

[外链图片转存中...(img-FVynzo9n-1712872878006)]

![img](https://img-blog.csdnimg.cn/img_convert/6c361282296f86381401c05e862fe4e9.png)

![img](https://img-blog.csdnimg.cn/img_convert/9f49b566129f47b8a67243c1008edf79.png)

**既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上前端开发知识点,真正体系化!**

**由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新**

**如果你觉得这些内容对你有帮助,可以扫码获取!!!(备注Python)**

<img src="https://img-community.csdnimg.cn/images/fd6ebf0d450a4dbea7428752dc7ffd34.jpg" alt="img" style="zoom:50%;" />
  • 18
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值