JAVA 1.8新特性
1 新特性介绍
# 什么是JAVA 1.8新特性?
2014年Oracle公司更新jdk版本后新增的特性
# 作用?
lambda表达式(简化匿名内部类代码)、方法引用(多用于流Stream)、新日期API
2 lambda表达式
2.1 lambda表达式使用
package com.qf.a_lambda;
import java.io.File;
import java.io.FileFilter;
import java.util.Comparator;
import java.util.Set;
import java.util.TreeSet;
import org.junit.Test;
/**
* lambda表达式
* - 简化匿名内部类的代码,在这里,该匿名内部类实现必须是函数式接口
* - 标记型接口:接口中没有方法,只作为标记使用,比如Serializable接口
* - 函数式接口:接口中只有一个方法,通常提供一个功能作为方法参数的形式传入,比如Runnable接口
*/
@SuppressWarnings("all")
public class LambdaTest {
// 1 函数式接口中的方法没有参数且没有返回值
@Test
public void test1() {
// 1.1 普通方式的线程任务
Runnable r1 = new Runnable() {
@Override
public void run() {
System.out.println("子线程启动...");
}
};
// 1.2 lambda表达式的线程任务(代码实现一般只有一行时)
Runnable r2 = () -> System.out.println("子线程启动...");
// 1.3 lambda表达式的线程任务(代码实现一般只有一行或多行时)
Runnable r3 = () ->{
System.out.println("子线程启动...");
};
new Thread(r3).start();
}
// 2 函数式接口中的方法有两个参数且有返回值
@Test
public void test2() {
// 2.1 普通方式的比较器(带上泛型)
Comparator<Integer> c1 = new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return o1 - o2;
}
};
// 2.2 lambda表达式的比较器(带上泛型,代码实现一般只有一行时)
Comparator c2 = (Object o1,Object o2) -> (Integer)o1 -(Integer)o2; // 不带泛型,很麻烦
Comparator<Integer> c3 = (o1, o2) -> o1 - o2;
// 2.3 lambda表达式的比较器(带上泛型,代码实现一般只有一行或多行时不能省略return关键字)
Comparator<Integer> c4 = (o1, o2) ->{
return o1 - o2;
};
Set<Integer> set = new TreeSet<>(c4);
set.add(3);
set.add(4);
set.add(1);
System.out.println(set);
}
// 3 函数式接口中的方法有一个参数且没有返回值
@Test
public void test3() {
// 3.1 普通方式的文件过滤器(带上泛型)
FileFilter f1 = new FileFilter() {
@Override
public boolean accept(File pathname) {
if(pathname.isFile() && pathname.getName().endsWith(".txt")) {
return true;
}
return false;
}
};
// 3.2 lambda表达式的比较器(带上泛型,代码实现一般只有一行或多行时不能省略return关键字)
FileFilter f2 = pathname ->{
if(pathname.isFile() && pathname.getName().endsWith(".txt")) {
return true;
}
return false;
};
File file = new File("a"); // 当前工程下的a目录
File[] files = file.listFiles(f2);
for(File f : files) {
System.out.println(f.getName());
}
}
}
2.2 jdk常用接口类型
package com.qf.a_lambda;
import java.util.Random;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;
/**
* jdk常用接口类型
*/
public class OfferInterfaceTest {
public static void main(String[] args) {
// 1 消费型接口(方法有参数,没有返回值)
Consumer<Integer> c1 = new Consumer<Integer>() {
@Override
public void accept(Integer t) {
System.out.println("t="+t);
}
};
c1.accept(100);
Consumer<Integer> c2 = t -> System.out.println("t="+t);
c2.accept(200);
// 2 供给型接口(方法无参,有返回值)
Supplier<Integer> s1 = new Supplier<Integer>() {
@Override
public Integer get() {
return new Random().nextInt(10);
}
};
System.out.println(s1.get());
Supplier<Integer> s2 = () -> new Random().nextInt(10);
System.out.println(s2.get());
// 3 函数型接口(只有一个方法)
Function<String, Integer> f1 = new Function<String, Integer>() {
@Override
public Integer apply(String t) {
return t.length();
}
};
System.out.println(f1.apply("Hello"));
Function<String, Integer> f2 = t -> t.length();
System.out.println(f2.apply("World"));
// 4 断言型接口(有参数,返回boolean类型)
Predicate<Integer> p1 = new Predicate<Integer>() {
@Override
public boolean test(Integer t) {
return t == 3;
}
};
System.out.println(p1.test(3));
Predicate<Integer> p2 = t -> t == 3;
System.out.println(p2.test(4));
}
}
2.3 lambda表达式案例
package com.qf.a_lambda;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.function.Predicate;
/**
* 集合中放入不同长度的字符串,通过lambda表达式的方法获取长度为3的字符串或长度大于4的字符串
*/
public class MyTest {
public static void main(String[] args) {
List<String> srcList = Arrays.asList(new String[] {"abc","bcd","ghdfe"});
// 长度等于3
List<String> destList = new GetListLength().getLength(srcList, t -> t.length() == 3);
System.out.println(destList);
// 长度大于4
List<String> destList2 = new GetListLength().getLength(srcList, t -> t.length() > 4);
System.out.println(destList2);
}
}
/**
* 获取集合长度的实现类
*/
class GetListLength implements GetLengthable{
@Override
public List<String> getLength(List<String> srcList, Predicate<String> predicate) {
if(srcList != null) {
List<String> list = new ArrayList<>();
for(String str : srcList) {
if(predicate.test(str)) {
list.add(str);
}
}
return list;
}
return null;
}
}
/**
* 获取集合长度的接口
*/
interface GetLengthable{
/**
* 获取长度
* @param srcList 原集合
* @param predicate 断言型接口
* @return 目标集合
*/
List<String> getLength(List<String> srcList, Predicate<String> predicate);
}
3 方法引用(多用于流Stream)
3.1 流的创建方式
package com.qf.a_lambda;
/**
* Stream
* -流,类似于集合。集合的作用的存储数据,而流的作用则是存储集合或数组的操作过程
*/
import java.util.Arrays;
import java.util.List;
import java.util.Random;
import java.util.stream.IntStream;
import java.util.stream.Stream;
import org.junit.Test;
public class StreamTest {
// 1 通过集合获取流对象
@Test
public void test1() {
List<Integer> list = Arrays.asList(new Integer[] {22,44,66,33});
// 1.1 获取流对象,注意,这里forEach会关闭流,只能调一次
Stream<Integer> stream = list.stream();
// Stream<Integer> stream2 = list.parallelStream(); // 多线程,会打乱元素位置
// stream.forEach(new Consumer<Integer>() { // 普通方式
// @Override
// public void accept(Integer t) {
// System.out.println(t);
// }
// });
// stream.forEach(t -> System.out.println(t)); // lambda方式
stream.forEach(System.out::println); // 1.2 方法引用
}
// 2 通过数组的工具类Arrays获取流对象
@Test
public void test2() {
Arrays.stream(new int[] {3,2,4}).forEach(System.out::println);
}
// 3 通过Stream类获取流对象
@Test
public void test3() {
// 3.1 of
Stream.of(3,4,2).forEach(System.out::println);
// 3.2 iterate
Stream.iterate(3, t -> t + 2).limit(3).forEach(System.out::println);
// 3.3 generate
Stream.generate(() -> new Random().nextInt(10)).limit(4).forEach(System.out::println);
}
// 4 通过IntStream类获取流对象(LongStream和DoubleStream类似)
@Test
public void test4() {
// 4.1 of
IntStream.of(3,4,2).forEach(System.out::println);
// 4.2 range -> [3, 6)
IntStream.range(3, 6).forEach(System.out::println);
// 4.3 rangeClosed -> [3, 6]
IntStream.rangeClosed(3, 6).forEach(System.out::println);
}
}
3.2 流的中间操作
package com.qf.a_lambda;
/**
* 流的常用中间操作
* - filter, limit, skip, distinct, sorted, map, parallel
*/
import java.util.Arrays;
import java.util.List;
import java.util.Random;
import java.util.stream.IntStream;
import org.junit.Test;
public class StreamMidTest {
private List<Student> list = Arrays.asList(new Student[] {
new Student("sunwukong", 500), new Student("tangsen",20),
new Student("bajie",600), new Student("shasen",660),
new Student("bajie",600)});
// 1 filter 过滤
@Test
public void test1() {
list.stream().filter(p -> p.getName().length() != 5).forEach(System.out::println);
}
// 2 limit 限制
@Test
public void test2() {
IntStream.generate(() -> new Random().nextInt(10)).limit(4).forEach(System.out::println);
}
// 3 skip 跳过
@Test
public void test3() {
list.stream().skip(2).forEach(System.out::println);
}
// 4 distinct 去重
@Test
public void test4() {
// 注意:元素需重写hashcode方法和equals方法
list.stream().distinct().forEach(System.out::println);
}
// 5 sorted 排序
@Test
public void test5() {
list.stream().sorted((p1, p2) -> p1.getAge() - p2.getAge()).forEach(System.out::println);
}
// 6 map 映射
@Test
public void test6() {
list.stream().map(p -> p.getName()).forEach(System.out::println);
}
// 7 parallel 多线程,性能提供,元素位置杂乱
@Test
public void test7() {
list.stream().parallel().forEach(System.out::println);
}
}
class Student{
private String name;
private Integer age;
public Student() {
}
public Student(String name, Integer age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((age == null) ? 0 : age.hashCode());
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Student other = (Student) obj;
if (age == null) {
if (other.age != null)
return false;
} else if (!age.equals(other.age))
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
@Override
public String toString() {
return "Student [name=" + name + ", age=" + age + "]";
}
}
3.3 流的最终操作
package com.qf.a_lambda;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import org.junit.Test;
/**
* 流的常用最终操作
* - forEach, min, max, count, reduce, collect
*/
public class StreamFinalTest {
private List<Student2> list = Arrays.asList(new Student2[] {
new Student2("sunwukong", 500), new Student2("tangsen",20),
new Student2("bajie",600), new Student2("shasen",660),
new Student2("bajie",600)});
// 1 forEach 循环遍历
@Test
public void test1() {
list.stream().forEach(System.out::println);
}
// 2 min 求最小数
@Test
public void test2() {
System.out.println(list.stream().min((s1, s2) -> s1.getAge() -s2.getAge()).get());
}
// 3 max 最大数
@Test
public void test3() {
System.out.println(list.stream().max((s1, s2) -> s1.getAge() -s2.getAge()).get());
}
// 4 count 计数量
@Test
public void test4() {
System.out.println(list.stream().count());
}
// 5 reduce 汇总
@Test
public void test5() {
System.out.println(list.stream().map(s -> s.getAge()).reduce((a1, a2) -> a1 + a2).get());
}
// 6 collect 返回集合
@Test
public void test6() {
System.out.println(list.stream().map(s -> s.getName()).collect(Collectors.toSet()));
}
}
class Student2{
private String name;
private Integer age;
public Student2() {
}
public Student2(String name, Integer age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((age == null) ? 0 : age.hashCode());
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Student2 other = (Student2) obj;
if (age == null) {
if (other.age != null)
return false;
} else if (!age.equals(other.age))
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
@Override
public String toString() {
return "Student [name=" + name + ", age=" + age + "]";
}
}
4 新日期API
package com.qf.a_lambda;
/**
* 新日期API
* -LocalDate, LocalTime, LocalDateTime, Instant, ZoneId
*/
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import org.junit.Test;
public class NewDateTest {
// 1 LocalDate 当前日期
@Test
public void localDateTest() {
LocalDate localDate = LocalDate.now();
// 当前日期
System.out.println(localDate);
}
// 2 LocalTime 当前时间
@Test
public void localTimeTest() {
LocalTime localTime = LocalTime.now();
// 当前时间
System.out.println(localTime);
}
// 3 LocalDateTime 当前日期时间
@Test
public void LocalDateTimeTest() {
LocalDateTime localDateTime = LocalDateTime.now();
// 当前日期时间
System.out.println(localDateTime);
// 年份
System.out.println(localDateTime.getYear());
// 月份,注意:这里月份从1开始,与Calendar日历类不同
System.out.println(localDateTime.getMonth().getValue());
// 日
System.out.println(localDateTime.getDayOfMonth());
// 时
System.out.println(localDateTime.getHour());
// 分
System.out.println(localDateTime.getMinute());
// 秒
System.out.println(localDateTime.getSecond());
}
// 4 Instant 时间戳
@Test
public void InstantTest() {
Instant instant = Instant.now();
// 当前时间戳
System.out.println(instant);
}
// 5 ZoneId 时区
@Test
public void ZoneIdTest() {
ZoneId zoneId = ZoneId.systemDefault();
// 当前时区
System.out.println(zoneId);
}
// 6 Date -> Instant -> LocalDateTime 转换
@Test
public void DateFormatTest() {
Date date = new Date();
Instant instant = date.toInstant();
LocalDateTime localDateTime = LocalDateTime.ofInstant(instant, ZoneId.systemDefault());
System.out.println(localDateTime);
}
// 7 LocalDateTime -> Instant -> Date 转换
@Test
public void LocalDateTimeFormatTest() {
LocalDateTime localDateTime = LocalDateTime.now();
Instant instant = localDateTime.atZone(ZoneId.systemDefault()).toInstant();
Date date = Date.from(instant);
System.out.println(date);
}
// 8 DateTimeFormatter 带格式日期
@Test
public void DateTimeFormatterTest() {
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
// 日期转字符串
String datetime = dtf.format(LocalDateTime.now());
System.out.println(datetime);
}
}
5 结语
结语,因为官方无节制地限制博客的上传,我新写的博客将在博客园上传,地址https://www.cnblogs.com/lll919397/