新特性
特点
(***)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:函数式接口检测