目录
- 接口的默认方法和静态方法
- Lambda表达式
- 1、匿名内部类
- 2、函数式接口(@FunctionalInterface)
- 2.1 无参函数式接口匿名内部类方式-->Lambda表达式方式
- 2.2 有参函数式接口匿名内部类方式-->Lambda表达式方式
- 3、Lambda实战
- 3.1 循环遍历
- 3.2 集合排序
- 3.3 创建线程
- 方法引用
- Optional
- Stream流
- 1、遍历、遍历筛选(foreach/filter)
- 2、聚合函数、排序(max/min/count/sorted)
- 3、映射(map)
- 4、规约(reduce)
- 5、收集、转换(collect)
- 新的日期API
接口的默认方法和静态方法
JDK8允许在接口中定义默认方法和静态方法(带有方法体)
public interface interfaceChange {//普通方法---public abstractvoid normalMethod();//默认方法---defaultdefault void defaultMethod(){System.out.println("我是jdk1.8中接口中的默认方法,带有方法体的!");}//静态方法---staticstatic void staticMethod(){System.out.println("我是jdk1.8中接口中的静态方法,带有方法体的!");}
}
public class InterfaceChangeImpl implements interfaceChange{//必须重写普通方法@Overridepublic void normalMethod() {System.out.println("我是重写接口的add方法!");}public static void main(String[] args) {InterfaceChangeImpl i = new InterfaceChangeImpl();//调用重写方法i.normalMethod();//调用默认方法i.defaultMethod();//调用静态方法interfaceChange.staticMethod();}
}
Lambda表达式
1、匿名内部类
当我们想使用接口中的方法,但是不想创建子类去重写再调用,我们就可以使用匿名内部类来实现快速简洁调用接口中的方法
//如果接口中只有一个方法
public static void main(String[] args) {new interfaceChange() {@Overridepublic void normalMethod() {System.out.println("通过匿名内部类实现的方法1!");}}.normalMethod();
}
//如果接口中有多个方法
public static void main(String[] args) {interfaceChange i = new interfaceChange() {@Overridepublic void normalMethod() {System.out.println("通过匿名内部类实现的方法1!");}@Overridepublic void normalMethod2() {System.out.println("通过匿名内部类实现的方法2!");}};i.normalMethod();i.normalMethod2();}
2、函数式接口(@FunctionalInterface)
2.1 无参函数式接口匿名内部类方式-->Lambda表达式方式
//无参
@FunctionalInterface//声明为函数式接口---只能有一个普通方法
public interface UserMapper {//普通方法void get();
}
//无参匿名内部类方式
new UserMapper() {@Overridepublic void get() {System.out.println("无参匿名内部类方式");}
}.get();
//无参Lambda表达式方式 ------方法体如果只有一条语句,可省略{ }
UserMapper u = () -> System.out.println("无参Lambda表达式方式");
u.get();
//更精简表达式
((UserMapper)()-> System.out.println("无参Lambda表达式方式")).get();
2.2 有参函数式接口匿名内部类方式-->Lambda表达式方式
//有参
@FunctionalInterface
public interface StudentMapper {public void select(String name,Integer age);
}
//有参匿名内部类方式
System.out.println(new StudentMapper() {@Overridepublic String select(String name, Integer age) {return name + "" + age;}}.select("Mike",20)
);//有参Lambda表达式方式
StudentMapper s = (x,y)-> x + "" + y; ----只有一条语句且有返回值,可省略return和{ }
System.out.println(s.select("Mike", 3));
//更精简表达式
System.out.println( ((StudentMapper) (x, y) -> x + "" + y).select("Mike", 40));
3、Lambda实战
3.1 循环遍历
List<Integer> list = Arrays.asList(20,54,10,
//实战---循环遍历
//Lambda方式
list.forEach(s-> System.out.println(s));
//stream流方式
list.stream().forEach(System.out::println);
3.2 集合排序
//实战---排序
//lambda方式
list.sort((x,y)->x-y);//正序
System.out.println("list = " + list);
list.sort((x,y)->y-x);//逆序
System.out.println("list = " + list);
//stream流方式
list.stream().sorted(Integer::compareTo).collect(Collectors.toList());//正序
list.stream().sorted(Comparator.comparing(Integer::intValue).reversed()).collect(Collectors.toList());//逆序
3.3 创建线程
//实战---线程
new Thread(()->{ System.out.println("线程开始!"); }).start();
方法引用
静态方法引用
类名::静态方法名
对象方法引用
类名::实例方法名
实例方法引用
对象实例::方法名
构造函数引用
类名::new
Optional
创建Optional容器:
public static void main(String[] args) {//创建一个空的Optional容器Optional<Object> empty = Optional.empty();//创建一个非空的Optional容器(参数必须有值)Student s = new Student("MIke",20,"大学");Optional<Student> op = Optional.of(s);//创建一个可接受null参数的Optional(主用)Optional<Student> s1 = Optional.ofNullable(s);
}
判断容器中是否为空:
//判断容器中是否为空
boolean present = op.isPresent(); 空->true,非空->false//判断容器中是否为空,并且可通过Lambda表达式进行下一步操作
op1.ifPresent(p->p.setName("李四"));
Optional.ofNullable(s).ifPresent(p->p.setAge(0)); //(主用)
System.out.println(s);
获取容器中的对象:
//获取容器中的对象
Student s1 = null;
Student s2 = new Student("Amy",55,"硕士");
//get() 如果为空报异常
Student student = Optional.ofNullable(s1).get();
//get() 正常则返回对象
Student student2 = Optional.ofNullable(s2).get();
//orElse() 如果为空则返回其他的对象,像三目运算符(s1==null?s2:s1)
Student student3 = Optional.ofNullable(s1).orElse(new Student("Jghn",44,"博士"));
//orElseThrow() 如果为空则抛出异常
Student student4 = Optional.ofNullable(s1).orElseThrow(()->new RuntimeException("对象为空!!"));
Stream流
1、遍历、遍历筛选(foreach/filter)
List<String> list = new ArrayList<>();
list.add("张三");
list.add("李四");
list.add("王五");
//普通遍历
list.stream().forEach(System.out::println);
//筛选遍历
list.stream().filter(s -> "张三".equals(s)||"李四".equals(s)).forEach(System.out::println);
List<Student> list1 = new ArrayList<>();
list1.add(new Student("Mike",20,"大学"));
list1.add(new Student("Amy",21,"大学"));
list1.add(new Student("Jhon",22,"高中"));
list1.add(new Student("Lihua",10,"初中"));
//普通遍历
list1.stream().forEach(System.out::println);
//筛选遍历并输出新的集合
List<Student> collect = list1.stream().filter(s -> s.getAge() <= 20).collect(Collectors.toList());
System.out.println("年龄小于等于20的学生:collect = " + collect);
//遍历筛选符合条件的元素并且指定属性返回
List<String> collect1 = list1.stream().filter(s -> "大学".equals(s.getGrade())).map(Student::getName).collect(Collectors.toList());
System.out.println("学历为大学的学生:collect1 = " + collect1);
2、聚合函数、排序(max/min/count/sorted)
max/min:
List<String> list2 = Arrays.asList("1","30","55","78","9999","55");
List<Integer> list3 = Arrays.asList(10,30,55,78,9999);
//取字符串最大长度
Optional<String> max = list2.stream().max(Comparator.comparing(String::length));
System.out.println("max = " + max.get());
//取Integer最大值
Optional<Integer> max1 = list3.stream().max((Integer::compareTo));
System.out.println("max1 = " + max1.get());
//取对象属性中年龄最大的
Optional<Student> max2 = list1.stream().max(Comparator.comparing(Student::getAge));
System.out.println("max2 = " + max2.get());---------最小值类推即可
count:
//计数
long count = list2.stream().filter(s -> "55".equals(s)).count();
System.out.println("属性为“55”的元素有:count = " + count);
long count1 = list1.stream().filter(s -> "大学".equals(s.getGrade())).count();
System.out.println("大学生有:count = " + count1);
sorted:
//方式一:
//正序
list.stream().sorted(Integer::compareTo).collect(Collectors.toList());//逆序
list.stream().sorted(Comparator.comparing(Integer::intValue).reversed()).collect(Collectors.toList());//方式二:
//正序
list.stream().sorted((x,y)->x-y).forEach(System.out::println);
list1.stream().sorted((x,y)->x.getAge()-y.getAge()).forEach(System.out::println);
//逆序
list.stream().sorted((x,y)->y-x).forEach(System.out::println);
list1.stream().sorted((x,y)->y.getAge()-x.getAge()).forEach(System.out::println);
3、映射(map)
List<String> list4 = Arrays.asList("abcd", "bcdd", "defde", "fTr");
//String类型集合将小写转大写
list4.stream().map(String::toUpperCase).forEach(System.out::println);
//Integer类型集合每个元素+5
List<Integer> integerList = list3.stream().map(s -> s += 5).collect(Collectors.toList());
System.out.println("每个元素+5之后的新integerList = " + integerList);
//实体集合将每个学生的年龄-5
List<Student> collect = list1.stream().map(s -> {Integer age = s.getAge();s.setAge(age -= 5);return s;
}).collect(Collectors.toList());
System.out.println("年龄全部-5的新集合是:collect = " + collect);
4、规约(reduce)
//Integer集合求和
Optional<Integer> reduce = list3.stream().reduce(Integer::sum);
//Optional<Integer> reduce = list3.stream().reduce((x, y) -> x + y);
System.out.println("和为:reduce = " + reduce.get());
//Integer集合求积
Optional<Integer> reduce1 = list3.stream().reduce((x, y) -> x * y);
System.out.println("积为:reduce1 = " + reduce1.get());
//String集合求组合
Optional<String> reduce2 = list4.stream().reduce((x, y) -> x + y);
System.out.println("组合为:reduce2 = " + reduce2.get());
//实体集合求年龄总和
Optional<Integer> reduce3 = list1.stream().map(Student::getAge).reduce(Integer::sum);
System.out.println("年龄总和为:reduce3 = " + reduce3.get());
5、收集、转换(collect)
从字面上去理解,就是把一个流收集起来,最终可以是收集成一个值也可以收集成一个新的集合。
collect
主要依赖java.util.stream.Collectors
类内置的静态方法。
收集成List:Collectors.toList()
收集成Set:Collectors.toSet() (注:对象收集要去重的话需要重写hashCode和toString)
收集成Map:Collectors.toMap()
List<Integer> list5 = Arrays.asList(1, 6, 3, 4, 6, 7, 9, 6, 20, 7);//将偶数收集起来
List<Integer> collect = list5.stream().filter(x -> x % 2 == 0).collect(Collectors.toList());
System.out.println("collect = " + collect);//将奇数收集起来并且不重复
Set<Integer> collect1 = list5.stream().filter(x -> x % 2 != 0).collect(Collectors.toSet());
System.out.println("collect1 = " + collect1);//将实体集合中年龄大于等于20的收集起来--List
List<Student> collect2 = list1.stream().filter(s -> s.getAge() >= 20).collect(Collectors.toList());
System.out.println("collect2 = " + collect2);//将实体集合中年龄小于等于20的收集起来--Map
Map<?, Student> collect3 = list1.stream().filter(s -> s.getAge() < 20).collect(Collectors.toMap(Student::getName, s -> s));
System.out.println("collect3 = " + collect3);
新的日期API
//1、设计不合理并且是可变的,线程不安全
Date date = new Date(2020,7,26);//2、时间格式化并且线程不安全
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
System.out.println(simpleDateFormat.format(date));
Date、Calendar、SimpleDateFormat都是线程不安全的。而JDK8加入了LocalDate、LocalTime、LocalDateTime、DateTimeFormatter通过加了Final修饰实现了不可变,解决线程安全问题。
//新的LocalDate
LocalDate localDate = LocalDate.now();
LocalDate localDate1 = LocalDate.of(2024,7,26);//新的LocalTime
LocalTime localTime = LocalTime.now();
LocalTime localTime1 = LocalTime.of(16,41,50);//新的LocalDateTime
LocalDateTime localDateTime = LocalDateTime.now();
LocalDateTime localDateTime1 = LocalDateTime.of(2024,7,26,16,41,50);//新的DateTimeFormatter
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ISO_LOCAL_DATE_TIME;
System.out.println(dateTimeFormatter.format(localDateTime));
DateTimeFormatter dateTimeFormatter1 = DateTimeFormatter.ofPattern("yyyy/MM/dd HH-mm-ss");
System.out.println(dateTimeFormatter1.format(localDateTime));