2021-11-11  2021-11-11    4757 字   10 分钟

新特性

特点

(***)1.Lambda表达式

(***)2.StreamAPI

3.对于时间类的增强。

4.Optional 用于处理空指针异常。

(**)5.接口中静态方法和默认方法

6.函数式接口。

7.HashMap底层: 哈希表+链表 ,但是1.8jdk 修改了 哈希表+ 链表/红黑树 ,阈值 大于 8 转树,小于6 链表

8.元空间 metaspace 元空间使用的是物理内存。方法区是一个逻辑概念,在1.7以前包含1.7,由永久代实现,1.8jdk由元 空间实现。 静态成员与字符串常量池在1.7jdk之后在堆中。但是逻辑上属于方法区。

接口中的默认方法

1.接口中默认方法引入的原因: ① 便于类的维护② 向下兼容。

2.关键字:

default

3.细节:

① 接口本身不能创建对象,如果要创建对象,只能通过子类来实现,默认方法也是通过子类来进行

调用,但是如果子类觉得该方法不适用,可以重写。

② 类优先原则:当接口与类中有同名方法时,如果接口中的是默认方法,那么,类优先,该子类调

用该方法时,使用的是类中的实现。

③ 当多个接口中,有同名默认方法时,如果这些接口,都由一个子类实现,该子类必须实现该默认

方法。

④ 接口中的默认方法在子类中如果需要调用,调用格式:

接口.super.方法名称(参数列表)

代码

package com.demo;
/**
  1.接口中的默认方法:① 向下兼容 ② 便于类的维护。
  2.细节问题:
     ① 接口中的默认方法,子类或子接口都继承该方法。可以根据需要进行重写。
     ② 当子类实现的接口与继承的类有同名默认方法时,类优先原则。
     ③ 当子类实现的多个接口中,有同名默认方法时,子类必须重写父接口的方法。
     ④ 如果子类重写了父接口的默认方法,还需要使用该父接口中的默认方法。
      格式:
        父接口的名称.super.方法名称()
 */
public class 接口中的默认方法 {
    public static void main(String[] args) {
        ZIT2 t = new ZIT2();
        t.fun1();
    }
}
interface T2{
    public void fun();
    //接口中默认方法。
    public default void fun1(){
        System.out.println("1111");
    };
}
interface T3{
    //接口中默认方法。
    public default void fun1(){
        System.out.println("33333");
    };
}
class M{
    public void fun1(){
        System.out.println("2222");
    }
}
class ZIT2 /*extends  M */implements  T2,T3{
    @Override
    public void fun() {

    }

    @Override
    public void fun1() {
        T2.super.fun1();
    }

}
class ZiT21 implements  T2{

    @Override
    public void fun() {

    }
}

接口的静态方法

1.接口中的静态方法:向类进行靠近

2.关键字:

static

3.调用格式:

接口的名称.方法名称()

4.接口中的静态方法不能被子类继承,只能通过接口的名称的形式,进行调用

代码

package com.demo;
/**
  1.接口中的静态方法:向类进行靠近
  2.关键字:
    static
  3.调用格式:
      接口的名称.方法名称()
  4.接口中的静态方法不能被子类继承,只能通过接口的名称的形式,进行调用。
 */
public class 接口的静态方法 {
    public static void main(String[] args) {
        T5.fun();
        ZiT5 t= new ZiT5();

    }
}
interface T5{
    public static void fun(){
        System.out.println(111);
    }

}
class ZiT5 implements  T5{

}

私有方法

1.9 接口私有方法。

Lambda表达式

1.概述

1.语法 :

格式:

(数据类型 参数名称,数据类型 参数名称) -> {

方法体;

return 返回值;

}

注意:

① 其中数据类型 参数名称,由于1.7jdk类型推断的出现,数据类型可以省略。没有参数的

情况下,()也不能省略

② -> 叫箭头符号 也叫lambda运算符

③ {}里面就是方法体的实现。

2.用途:

Lambda表达式是匿名内部类的简化书写。该匿名内部类必须是一个接口,该接口中有且只有一

个抽象方法。

不能是一个类。

3.函数式接口:

接口,该接口中有且只有一个抽象方法

4.@FunctionalInterface 该注解可以校验是否为函数式接口。

package com.demo;

/**

1.语法 :

格式:

(数据类型 参数名称,数据类型 参数名称) -> {

方法体;

}

注意:

① 其中数据类型 参数名称,由于1.7jdk类型推断的出现,数据类型可以省略。没有参数的

情况下,()也不能省略

② -> 叫箭头符号 也叫lambda运算符

③ {}里面就是方法体的实现。

2.用途:

Lambda表达式是匿名内部类的简化书写。该匿名内部类必须是一个接口,该接口中有且只有一

个抽象方法。

不能是一个类。

3.函数式接口:

接口,该接口中有且只有一个抽象方法

4.@FunctionalInterface 该注解可以校验是否为函数式接口。

*/

public class Lambda表达式 {

public static void main(String[] args) {

/* new T(){

@Override

public void fun() {

}

};*/

new T(){
@Override

public void fun() {

}

};

// 简化

T t= ()->{

System.out.println("aaaa");

};

T t1= ()->{

System.out.println("bbbb");

};

t.fun();

t1.fun();

//类

/* new F(){

@Override

public void sf() {

super.sf();

}

};*/

// F f = ()->{};

}

}

@FunctionalInterface

interface T{

public void fun();

// public void fun1();

}

/*

class F{

public void sf(){}

}*/

lambda表达式的格式

1.如果{}的方法体中语句只有一句,可以省略大括号不写。

2.对于lambda表达式来说,()中的数据类型可以省略。并且参数名称可以是任意的标识符。

3.如果lambda表达式中,小括号里面的参数只有一个,lambda表达式的小括号也可以省略。

4.如果lambda表达式中,方法体有返回值,并且只有返回值一句,{}和return都可以省略。

package com.demo;

/**

1.如果{}的方法体中语句只有一句,可以省略大括号不写。

2.对于lambda表达式来说,()中的数据类型可以省略。并且参数名称可以是任意的标识符。

3.如果lambda表达式中,小括号里面的参数只有一个,lambda表达式的小括号也可以省略。

4.如果lambda表达式中,方法体有返回值,并且只有返回值一句,{}和return都可以省略。

*/

public class Lambda表达式的书写格式 {

public static void main(String[] args) {

/*M m = ()->{

System.out.println("aaaa");

};*/

// 简化

/* M m= ()-> System.out.println("aaaa");

m.fun();*/

/* M1 m1 = (b)->{

System.out.println("bbbb");

};*/

//简化

/* M1 m1=b-> System.out.println(b);

m1.mf(12);*/

/* M2 m2 = (a,b)->{

System.out.println(a+b);

};*/

/*M3 m3= a ->{

return a;

};*/

//简化

M3 m3 = a-> a;

int i = m3.mf3(12);

System.out.println(i);

}

}

interface M{

public void fun();

}

interface M1{

public void mf(int a);

}

interface M2{

public void mf2(String a,int b);

}

interface M3{

public int mf3(int a);

}

方法引用

1.概述 1.方法引用:

① 对象::方法名称

② 类名::方法名称

注意:

1》 ::双冒号运算符,也叫方法引用运算符

2》方法引用是对lambda的进一步简化,当lambda表达式的方法体是由已有方法实现,可以通

过调用方法的格式进行简化。

package com.demo;

/**

1.方法引用:

① 对象::方法名称

② 类名::方法名称

注意:

1》 ::双冒号运算符,也叫方法引用运算符
2》方法引用是对lambda的进一步简化,当lambda表达式的方法体是由已有方法实现,可以通

过调用方法的格式进行简化。

*/

public class 方法引用 {

public static void main(String[] args) {

// TM t = a ->Integer.valueOf(a);

//简化

/*TM t = Integer::valueOf;

System.out.println(t.fun("123"));*/

/* TM1 t1 = a -> System.out.println(a);

t1 = System.out::println;*/

FM f = new FM();

// TM1 t2 = a ->f.n(a);

//简化

TM1 t2 = f::n;

FM1 fm = new FM1();

// TM2 t3 = (a,b)-> fm.kk1(a,b);

TM2 t3 = FM1::kk1;

t3.add(1,2);

}

}

interface TM{

public int fun(String a);

}

interface TM1{

public void k(String a);

}

class FM{

public void n(String a){

System.out.println(a);

}

}

interface TM2{

public void add(int a,int b);

}

class FM1{

public static void kk1(int a,int b){

System.out.println(a+b);

}

}

四大函数式接口

1.概述 1.四大函数式接口:

1>Consumer 消费型接口

Consumer<T>:accept(T t)

常用方法:

andThen(Consumer) 先执行对象的accept,再执行参数的accept。

2>Supplier 供给型接口

Supplier<T> T get()

package com.demo;

import java.util.function.Consumer;

import java.util.function.Supplier;

/**

1.四大函数式接口:

1>Consumer 消费型接口

Consumer<T>:accept(T t)

常用方法:

andThen(Consumer) 先执行对象的accept,再执行参数的accept。

2>Supplier 供给型接口

Supplier<T> T get()

Function 函数型接口

Predicate 断言型接口

*/

public class 四大内置函数式接口 {

public static void main(String[] args) {

Consumer<String> con = a-> System.out.println("aaaa");

// Consumer<String> con = System.out::println;

// con.accept("abc");

/*Consumer<String> con1 = a->{

System.out.println("bbbb");

};

Consumer<String> con2 = con.andThen(con1);

con2.accept("mm");*/

// 2>Supplier 供给型接口

// Supplier<T> T get()

Supplier<Integer> sl = ()->5;

Integer it = sl.get();

System.out.println(it);

}

}

断言型接口 1.Predicate 断言型接口

Predicate<T> boolean test(T t) 断言 测试:

2.常用方法:

① and && 与

② or ||或

③ negate() !非

package com.demo;

import java.util.function.Predicate;

/**

1.Predicate 断言型接口

Predicate<T> boolean test(T t) 断言 测试:

2.常用方法:

① and && 与
② or ||或

③ negate() !非

*/

public class 四大内置函数式接口1 {

public static void main(String[] args) {

Predicate<Integer> p = t -> t>5;

// System.out.println(p.test(10));

Predicate<Integer> p1 = t -> t<20;

//要求t>5 并且t<20

Predicate<Integer> p2 = p.and(p1);

// System.out.println(p2.test(22));

//要求t>5或t<20

Predicate<Integer> p3 = p.or(p1);

//t<=5

Predicate<Integer> p4 = p.negate();

System.out.println(p4.test(-13));

}

}

4.函数型接口

package com.demo;

import java.util.function.Function;

/**

1.Function 函数型接口:

Function<T,R> R apply(T t)

2.常用方法:

<V> Function<T,V> andThen(Function<? super R,? extends V> after)

*/

public class 四大内置函数式接口之函数型接口 {

public static void main(String[] args) {

Function<String,Integer> fc = t->{

System.out.println(1111);

return Integer.valueOf(t);

};

// Integer value = fc.apply("123");

// System.out.println(value);

// Function<String ,String> fc1 = t->t.concat("abc");

// System.out.println(fc1.apply("bcd"));

Function<Integer,String> fc3= t->{

System.out.println(222);

return t.toString();

};

Function<String,String> fc2 = fc.andThen(fc3);

//先执行对象的apply方法然后再执行参数的apply方法。

System.out.println(fc2.apply("123"));;

}

}

StreamAPI

1.概念

StreamAPI:对集合这样的数据的查找 过滤 筛选 等操作的补充,流本身不是数据源,不能存储数据

的。

2.Stream对象的获取

Collection

① parallelStream() 获取的并行流

② stream() 获取串行流

Stream

① of(T… values) 获取串行流

3.Stream工作原理

① 获取Stream流对象

② 中间操作(惰性求值:没有终止操作,不执行)

③ 终止操作

4.常用方法

package com.demo;

import java.util.Optional;

import java.util.stream.Stream;

/**

1.中间操作:

① concat(Stream<? extends T> a, Stream<? extends T> b) 合并流

② distinct() 去重复

注意:

对于自定义类,要注意重写equals方法。才能去重复

③ filter(Predicate<? super T> predicate) 过滤

④ limit(long maxSize) 截取参数为最大值

⑤ map(Function<? super T,? extends R> mapper) 映射

注意:

映射是根据返回值来映射新的流元素。

⑥ skip(long n) 跳过 n从1开始

2.终止操作:

① count() 统计个数,返回值为long类型

② forEach(Consumer<? super T> action) 对流中所有元素执行该操作

③ max(Comparator<? super T> comparator) /min(Comparator<? super T>

comparator) 求最大/小值

*/

public class StreamAPI常用方法 {

public static void main(String[] args) {

/*Stream<Integer> it = Stream.of(1, 2, 3, 4, 5);

Stream<Integer> it1 = Stream.of(6,7,8,9,10);

Stream<Integer> concat = Stream.concat(it, it1);

concat.filter(t->t>5).forEach(System.out::println);*/

// ① count() 统计个数,返回值为long类型

/*long count = Stream.of(1, 2, 3, 4, 5, 6, 7).count();

System.out.println(count);*/

// ② distinct() 去重复

// Stream.of(1, 2, 3, 4, 5, 6,

7,6,3).distinct().forEach(System.out::println);

//对于自定义类,要注意重写equals方法。才能去重复

// Stream.of(new Person("张三",19),new Person("张

",19)).distinct().forEach(System.out::println);

// ④ limit(long maxSize) 截取参数为最大值

// Stream.of(1,2,3,4,5,6,7).limit(8).forEach(System.out::println);

// ⑤ map(Function<? super T,? extends R> mapper) 映射

// Stream.of(1,2,3,4,5,6,7).map(t->t+3).forEach(System.out::println);

//涨工资

/*Stream.of(new Person("张三",19),new Person("张三1",20),new Person("张三

2",21)).map(

t->new Person(t.name,t.age+3)).forEach(System.out::println);*/

// ③ max(Comparator<? super T> comparator) /min(Comparator<? super T>

comparator) 求最大/小值

// Optional<Integer> max = Stream.of(1, 2, 3, 4, 5, 6, 7, -10, 20,

-19).max((x, y) -> x - y);

// //get() 获取该类对象的封装的值

// System.out.println(max.get());

//Optional 用于空指针的处理,防止空指针异常

// String msg = null;

// Optional<String> value = Optional.of(msg);
// Optional<String> value2 = Optional.ofNullable(msg);

}

}

class Person{

String name;

int age;

public Person() {

}

public Person(String name, int age) {

this.name = name;

this.age = age;

}

@Override

public boolean equals(Object o) {

if (this == o) return true;

if (o == null || getClass() != o.getClass()) return false;

Person person = (Person) o;

if (age != person.age) return false;

return name != null ? name.equals(person.name) : person.name == null;

}

@Override

public int hashCode() {

int result = name != null ? name.hashCode() : 0;

result = 31 * result + age;

return result;

}

@Override

public String toString() {

return "Person{" +

"name='" + name + '\'' +

", age=" + age +

'}';

}

}

2.常用方法

package com.demo;

import java.util.List;

import java.util.stream.Collectors;

import java.util.stream.Stream;

/**

1.sorted() 按自然顺序排序 中间操作

2.sorted(Comparator<? super T> comparator) 根据第三方比较器进行排序

(***) 3.collect(Collector<? super T,A,R> collector)Stream流转集合

注意:

通过Collectors获取Collector子类对象。

1》 toXXX

toList

toSet

toMap

*/

public class StreamAPI常用方法一 {

public static void main(String[] args) {

// 1.sorted() 按自然顺序排序 中间操作

// Stream.of(1,-15,20,32,47,-50).sorted().forEach(System.out::println);

// Stream.of("-1","1","111","22","123").sorted((x,y)->Integer.valueOf(x)-

Integer.valueOf(y)).forEach(System.out::println);

// 3.collect(Collector<? super T,A,R> collector)Stream流转集合

List<Integer> list = Stream.of(1, 2, 3, 4, 5, 6,

7).collect(Collectors.toList());

}

}

注解

1.概述

注释:对代码的解释说明。

注解:Annotation。

注解理解为代码里的特殊标记,这些标记可以在编译,类加载,运行时被读取, 并 执行相应的处理

注解的作用

① 文档提取:javadoc API @author @since

② 编译检测:@FunctionalInterface @Override

③ 代码依赖:@service @Controller 主要是代替配置文件。

3.自定义注解

[权限修饰符] @interface 注解的名称{

数据类型[] 属性名称() default 默认值;

数据类型[] 属性名称() default 默认值;

}

注意:数据类型,可以是String 基本数据类型 Class类型,这些类型可以是数组形式 ,其余不行。

如果自定义注解中 ,属性的名称为value,在调用时,可以省略value的名称。

package com.demo;

import java.util.Scanner;

/**

1.自定义注解格式:

[权限修饰符] @interface 注解的格式{

数据类型[] 属性名称() default 默认值;

}

注意:

其中 属性名称前的数据类型: 可以是基本数据类型,也可以是字符串,还可以Class类型

*/

public class 自定义注解 {

public static void main(String[] args) {

Scanner sc = new Scanner(System.in);

String s1= sc.nextLine();

}

}

@MyAnnation(value ="kk",cs={int.class,String.class})

class M{

@MyAnnation(cs={String.class,double.class},value = "ff")

public void fun(){

}

}

@interface MyAnnation{

String value() default "mm";

//数组

Class[] cs();

}

4.元注解

package com.demo;

import java.lang.annotation.*;

/**

1.元注解:

注解的注解。

2.作用:用来修饰限定注解的注解。

3.常见元注解:

1》@Target 表示可以修饰的成员 ElementType: TYPE FIELD METHOD

2》@Retention 表示注解的生命周期(***)。

RetentionPolicy:

SOURCE 编译期存在

CLASS 在class文件中存在

RUNTIME 运行期存在。

3》@Documented: 注解写入文档

4》@Inherited : 子类继承父类的注解(子类没有任何注解修饰)

*/

public class 元注解 {

public static void main(String[] args) {

Class clazz = N.class;

//注意:一个自定义注解,如果想在运行期能够获取,必须使用生命周期为Runtime。

Annotation value = clazz.getAnnotation(My1.class);

System.out.println(value);

Class clazz1 = ZiN.class;

Annotation value2 = clazz1.getAnnotation(My1.class);

System.out.println(value2);

N n = new N();

n.fun();

//抑制编译器警告

@SuppressWarnings("unused")

int a = 5;

}

}

@My1

class N{

@My1

@Deprecated //已过时

public void fun(){

}

}

@Inherited

@Retention(RetentionPolicy.RUNTIME)

@Target({ElementType.METHOD,ElementType.TYPE})

@interface My1{

String value() default "kk";

}

class ZiN extends N{

}

常见注解

@Deprecated:用于标志过时的类方法和成员变量

@Override:用于修饰重写的方法

@SuppressWarnings:用户忽略警告

@FunctionalInterface函数式接口检测


avatar
青山
悟已往之不谏 知来者之可追
一言
今日诗词
站点信息
本站访客数 :
本站总访问量 :