目录 一、Lambda 表达式 (一)Lambda 表达式语法 (二)类型推断 二、函数式接口 (一)自定义函数式接口 (二)作为参数传递Lambda 表达式 (三)Java 内置四大核心函数式接口 三、方法引用 四、Stream API
目录
(一)使用LocalDate、LocalTime、LocalDateTime
// 原来的匿名内部类 @Test public void test1() { Comparator com = new Comparator() { @Override public int compare(Integer o1, Integer o2) { return Integer.compare(o1, o2); } }; TreeSet ts = new TreeSet<>(com); } // Lambda表达式 @Test public void test2() { Comparator com = (o1, o2) -> Integer.compare(o1, o2); TreeSet ts = new TreeSet<>(com); }
语法格式一:无参,无返回值,Lambda体只需一条语句
语法格式二:Lambda需要一个参数
语法格式三:Lambda只需要一个参数时,参数的小括号可以省略
语法格式四:Lambda需要两个参数,并且有返回值
语法格式五:当 Lambda 体只有一条语句时,return 与大括号可以省略
其他子接口(参数个数)
public class TestLambda02 { @Test public void test04() { List stringList = Arrays.asList("hello", "world","you"); List list = getStringList(stringList, (s) -> s.length() > 3); list.forEach(System.out::println); } public List getStringList(List stringList, Predicate pre) { List strings = new ArrayList<>(); for (String s : stringList) { if(pre.test(s)) { strings.add(s); } } return strings; } @Test public void test03() { String string = getString("\t\t\t 帅哥好帅", (str) -> str.trim()); System.out.println(string); } public String getString(String str, Function func) { return func.apply(str); } @Test public void test02() { int num = 10; generator(num, () -> (int)(Math.random() * 100) + 1); } public void generator(int x, Supplier sup) { List integerList = new ArrayList<>(); for(int i = 0; i < x; i ++) { Integer integer = sup.get(); integerList.add(integer); } integerList.forEach(System.out::println); } @Test public void test01() { int num = 100; consumer(num, x -> System.out.println("消费了" + num + "元")); } public void consumer(int num, Consumer com) { com.accept(num); }}
public class TestMethodRef { // 数组引用 @Test public void test05() { Function func = (x) -> new String[x]; String[] strings = func.apply(10); System.out.println(strings.length); Function func2 = String[]::new; String[] strs = func2.apply(20); System.out.println(strs.length); } // 构造器引用 @Test public void test04() { Supplier sup = () -> new Employee(); // 构造器引用的方式 Supplier sup2 = Employee::new; Employee employee = sup2.get(); System.out.println(employee); Function func = Employee::new; Employee employee1 = func.apply(20); System.out.println(employee1); } // 类::实例方法名 @Test public void tes03() { // 规则:若Lambda参数列表中的第一参数是实例方法的调用者,第二参数是实例方法的参数时,此时 // 可以通过 class::method BiPredicate bp = (x, y) -> x.equals(y); BiPredicate bp1 = String::equals; } // 对象::静态方法 @Test public void test02() { Comparator com = (x, y) -> Integer.compare(x, y); Comparator com1 = Integer::compare; } // 对象::实例方法 @Test public void test01() { PrintStream ps = System.out; Consumer con = (x) -> System.out.println(x); Consumer con2 = ps::println; }}
方式一:Collection接口
Java8 中的 Collection 接口被扩展,提供了 两个获取流的方法 : ⚫ default Stream方式二:数组创建流
Java8 中的 Arrays 的静态方法 stream() 可 以获取数组流: ⚫ staticpublic class testStream { // 创建stream @Test public void test1() { //1.可以通过Collection 系列集合提供的stream() or parallelStream() List list = new ArrayList<>(); Stream stream1 = list.stream(); //2. 通过Arrays的静态方法stream()获取数组流 Employee[] emps = new Employee[2]; Stream stream2 = Arrays.stream(emps); //3. 通过stream的静态方法of() Stream stream3 = Stream.of(1, 2, 3); //4. 创建无限流 // 迭代 Stream stream4 = Stream.iterate(0, (x) -> x + 2); stream4.limit(10).forEach(System.out::println); // 生成 Stream stream5 = Stream.generate(Math::random); stream5.limit(10).forEach(System.out::println); }}
映射
排序
public class testStreamApi { List empList = Arrays.asList( new Employee("张三", 50, 7777.77), new Employee("李四", 35, 8888.6), new Employee("王五", 20, 999.55), new Employee("赵六", 40, 1000.5), new Employee("赵六", 40, 1000.5), new Employee("赵六", 40, 1000.5)); // 中间操作 @Test public void test06() { List strs = Arrays.asList("aaa", "bbb", "ccc"); strs.stream() .sorted() // 按已经实现的comparator接口的排序规则进行排序称为自然排序 .forEach(System.out::println); // 先按年龄排序,然后按姓名排序 empList.stream() .sorted((x, y) -> { if(x.getAge().equals(y.getAge())) { return x.getName().compareTo(y.getName()); } return x.getAge().compareTo(y.getAge()); }) .forEach(System.out::println); } @Test public void test05() { List stringList = Arrays.asList("aaa", "bbb", "ccc"); stringList.stream() .map((str) -> str.toUpperCase()) .forEach(System.out::println); System.out.println("---------------------------------"); // 获取员工的名字 empList.stream() .distinct() .map(Employee::getName) .forEach(System.out::println); System.out.println("---------------------------------"); // map实现将每个字符串转化为字符 复杂 Stream> streamStream = stringList.stream() .map(testStreamApi::filterCharacter); streamStream.forEach((sm) -> { sm.forEach(System.out::println); }); System.out.println("---------------------------------"); // flatMap实现将每个字符串转化为字符 简单 Stream stream = stringList.stream() .flatMap(testStreamApi::filterCharacter); stream.forEach(System.out::println); } public static Stream filterCharacter(String str) { List list = new ArrayList<>(); for(Character ch : str.toCharArray()) { list.add(ch); } return list.stream(); } @Test public void test04() { empList.stream() .filter((e) -> e.getAge() > 30) .skip(2) .distinct() // 这里是根据hashCode和equals,所以employee需要重写hashCode和equals .forEach(System.out::println); } @Test public void test03() { empList.stream() .filter((e) -> e.getAge() > 30) .limit(2) .forEach(System.out::println); } // 内部迭代:即stream内部帮我们迭代 @Test public void test01() { // 中间操作 Stream stream = empList.stream() .filter((e) -> e.getAge() > 30); // 终止操作:一次性执行全部内容,即“惰性求值” stream.forEach(System.out::println); } // 外部迭代 @Test public void test02() { Iterator iterator = empList.iterator(); while(iterator.hasNext()) { Employee employee = iterator.next(); if(employee.getAge() > 30) { System.out.println(employee); } } }}
public class testStreamApi2 { List empList = Arrays.asList( new Employee("张三", 50, 7777.77, Employee.Status.FREE), new Employee("李四", 35, 8888.6, Employee.Status.BUSY), new Employee("王五", 20, 999.55, Employee.Status.VOCATION), new Employee("赵六", 40, 1000.5, Employee.Status.BUSY), new Employee("赵六", 40, 1000.5, Employee.Status.FREE), new Employee("赵六", 40, 1000.5, Employee.Status.VOCATION)); // 其他 @Test public void test09() { DoubleSummaryStatistics ssd = empList.stream() .collect(Collectors.summarizingDouble(Employee::getSalary)); System.out.println(ssd.getAverage()); System.out.println(ssd.getMax()); System.out.println(ssd.getMin()); String str = empList.stream() .map(Employee::getName) .collect(Collectors.joining(",", "===", "===")); System.out.println(str); } // 分区 @Test public void test08() { // 分成true和false两个区 Map> map = empList.stream() .collect(Collectors.partitioningBy((e) -> e.getSalary() > 5000)); System.out.println(map); } // 多级分组 @Test public void test07() { Map>> map = empList.stream() .collect(Collectors.groupingBy(Employee::getStatus, Collectors.groupingBy((e) -> { if (e.getAge() < 30) { return "青年"; } else if (e.getAge() < 50) { return "中年"; } else { return "老年"; } }))); System.out.println(map); } // 分组 @Test public void test06() { Map> map = empList.stream() .collect(Collectors.groupingBy(Employee::getStatus)); System.out.println(map); } @Test public void test05() { Long size = empList.stream() .collect(Collectors.counting()); System.out.println(size); Double avg = empList.stream() .collect(Collectors.averagingDouble(Employee::getSalary)); System.out.println(avg); Double sum = empList.stream().collect(Collectors.summingDouble(Employee::getSalary)); System.out.println(sum); Optional max = empList.stream() .map(Employee::getSalary) .collect(Collectors.maxBy(Double::compareTo)); System.out.println(max.get()); Optional min = empList.stream() .collect(Collectors.minBy((x, y) -> Double.compare(x.getSalary(), y.getSalary()))); System.out.println(min.get()); } @Test public void test04() { List list1 = empList.stream() .map(Employee::getName) .collect(Collectors.toList()); list1.forEach(System.out::println); System.out.println("------------------------"); Set set = empList.stream() .map(Employee::getName) .collect(Collectors.toSet()); set.forEach(System.out::println); System.out.println("------------------------"); LinkedHashSet hashSet = empList.stream() .map(Employee::getName) .collect(Collectors.toCollection(LinkedHashSet::new)); hashSet.forEach(System.out::println); } @Test public void test03() { List list = Arrays.asList(1, 2, 3); Integer sum1 = list.stream() .reduce(1, (x, y) -> x + y); System.out.println(sum1); Optional sum2 = empList.stream() .map(Employee::getSalary) .reduce(Double::sum); System.out.println(sum2.get()); } @Test public void test02() { // 数量 long count = empList.stream() .count(); System.out.println(count); // 最大值 Optional max = empList.stream() .max((x, y) -> Double.compare(x.getSalary(), y.getSalary())); System.out.println(max.get().getSalary()); // 最小值 Optional min = empList.stream() .map(Employee::getSalary) .min(Double::compareTo); System.out.println(min.get()); } @Test public void test01() { boolean b1 = empList.stream() .allMatch((e) -> e.getStatus().equals(Employee.Status.FREE)); System.out.println(b1); boolean b2 = empList.stream() .anyMatch((e) -> e.getStatus().equals(Employee.Status.FREE)); System.out.println(b2); boolean b3 = empList.stream() .noneMatch((e) -> e.getStatus().equals(Employee.Status.FREE)); System.out.println(b3); // 返回的值有可能为空所以封装到了Optional Optional op1 = empList.stream() .sorted((x, y) -> Double.compare(x.getSalary(), y.getSalary())) .findFirst(); System.out.println(op1.get()); Optional op2 = empList.stream() .sorted((x, y) -> Double.compare(x.getSalary(), y.getSalary())) .findAny(); System.out.println(op2.get()); }}
案例:
public class testStreamApi3 { @Test public void test() { Integer[] num = new Integer[]{1, 2, 3, 4, 5}; Stream stream = Arrays.stream(num); stream.map(x -> x*x).forEach(System.out::println); } List empList = Arrays.asList( new Employee("张三", 50, 7777.77), new Employee("李四", 35, 8888.6), new Employee("王五", 20, 999.55), new Employee("赵六", 40, 1000.5), new Employee("赵六", 40, 1000.5), new Employee("赵六", 40, 1000.5)); @Test public void test2() { Optional sum = empList.stream() .map(e -> 1) .reduce(Integer::sum); System.out.println(sum.get()); }}
public interface MyPredicate { public boolean test(Employee employee);}==================================================================== List empList = Arrays.asList( new Employee("张三", 50, 7777.77), new Employee("李四", 35, 8888.6), new Employee("王五", 20, 999.55), new Employee("赵六", 40, 1000.5) ); // 需求:获取当前公司中员工年龄大于35的员工 @Test public void test3() { List employees = filterList(empList); for (Employee employee : employees) { System.out.println(employee); } System.out.println("---------------------------------"); employees = filterListBySalary(empList); for (Employee employee : employees) { System.out.println(employee); } } public List filterList(List empList) { List emps = new ArrayList<>(); for (Employee emp : empList) { if(emp.getAge() > 35) { emps.add(emp); } } return emps; } // 需求:获取当前公司中员工工资大于4000的员工 public List filterListBySalary(List empList) { List emps = new ArrayList<>(); for (Employee emp : empList) { if(emp.getSalary() > 4000) { emps.add(emp); } } return emps; } // 优化方式一:策略设计模式 @Test public void test4() { List employees = filterList(empList, new filterEmployeeByAge()); for (Employee employee : employees) { System.out.println(employee); } System.out.println("--------------------------------"); employees = filterList(empList, new filterEmployeeBySalary()); for (Employee employee : employees) { System.out.println(employee); } } public List filterList(List empList, MyPredicate pre) { List emps = new ArrayList<>(); for (Employee emp : empList) { if(pre.test(emp)) { emps.add(emp); } } return emps; } // 优化方式二:匿名内部类 @Test public void test5() { List emps = filterList(empList, new MyPredicate() { @Override public boolean test(Employee employee) { return employee.getSalary() > 4000; } }); emps.forEach(System.out::println); } // 优化方式三:Lambda表达式 @Test public void test6() { List employees = filterList(empList, e -> e.getSalary() > 4000); employees.forEach(System.out::println); } // 优化方式四:streamApi @Test public void test7() { empList.stream() .filter(e -> e.getSalary() > 4000) .limit(1) .forEach(System.out::println); System.out.println("-----------------------"); empList.stream() .map(Employee::getName) .forEach(System.out::println); }
public class testSimpleDateFORMat { public static void main(String[] args) throws ExecutionException, InterruptedException { SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd"); Callable task = new Callable() { @Override public Date call() throws Exception { return sdf.parse("20230518"); } }; ExecutorService pool = Executors.newFixedThreadPool(10); List> results = new ArrayList<>(); for(int i = 0; i < 10; i ++) { results.add(pool.submit(task)); } for(Future future:results) { System.out.println(future.get()); } pool.shutdown(); }}
以前的方式,加锁,这里使用ThreadLocal
public class DateFormatThreadLocal { private static final ThreadLocal df = new ThreadLocal(){ protected DateFormat initialValue() { return new SimpleDateFormat("yyyyMMdd"); } }; public static Date convert(String source) throws ParseException { return df.get().parse(source); }}=========================================================================public class testSimpleDateFormat { public static void main(String[] args) throws ExecutionException, InterruptedException {// SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd"); Callable task = new Callable() { @Override public Date call() throws Exception {// return sdf.parse("20230518"); return DateFormatThreadLocal.convert("20230518"); } }; ExecutorService pool = Executors.newFixedThreadPool(10); List> results = new ArrayList<>(); for(int i = 0; i < 10; i ++) { results.add(pool.submit(task)); } for(Future future:results) { System.out.println(future.get()); } pool.shutdown(); }}
jdk1.8的时间类
public class testSimpleDateFormat { public static void main(String[] args) throws ExecutionException, InterruptedException { DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyyMMdd"); Callable task = new Callable() { @Override public LocalDate call() throws Exception { return LocalDate.parse("20230518", dtf); } }; ExecutorService pool = Executors.newFixedThreadPool(10); List> results = new ArrayList<>(); for(int i = 0; i < 10; i ++) { results.add(pool.submit(task)); } for(Future future:results) { System.out.println(future.get()); } pool.shutdown(); }}
public class testLocalDateTime { // ZonedDate/ZonedTime/ZonedDateTime 时区相关的 @Test public void test8() { // 获得的是指定时区的当前时间 LocalDateTime ldt = LocalDateTime.now(ZoneId.of("Asia/Shanghai")); System.out.println(ldt); LocalDateTime ldt2 = LocalDateTime.now(); ZonedDateTime zdt = ldt2.atZone(ZoneId.of("Asia/Shanghai")); // 输出2023-05-18T22:01:45.684+08:00[Asia/Shanghai] // +08:00 是距离UTC的时间差 System.out.println(zdt); } @Test public void test7() { // 获取支持的时区 Set set = ZoneId.getAvailableZoneIds(); set.forEach(System.out::println); } // DateTimeFormatter : 格式化时间/日期 @Test public void test6() { DateTimeFormatter dtf1 = DateTimeFormatter.ISO_DATE; LocalDateTime ldt1 = LocalDateTime.now(); System.out.println(ldt1.format(dtf1)); System.out.println("-------------------------------"); // 格式化 DateTimeFormatter dtf2 = DateTimeFormatter.ofPattern("yyyy年MM月dd日 HH:mm:ss"); String time = ldt1.format(dtf2); System.out.println(time); // 再格式化回去 LocalDateTime ldt2 = ldt1.parse(time, dtf2); System.out.println(ldt2); } // TemporalAdjuster: 时间矫正器 @Test public void test5() { LocalDateTime ldt1 = LocalDateTime.now(); System.out.println(ldt1); // 直接设置日期为哪一天,不太方便求下一个周几等的操作 LocalDateTime ldt2 = ldt1.withDayOfMonth(10); System.out.println(ldt2); // 求下一个星期日 LocalDateTime ldt3 = ldt1.with(TemporalAdjusters.next(DayOfWeek.SUNDAY)); System.out.println(ldt3); //自定义:下一个工作日 LocalDateTime ldt5 = ldt1.with((l) -> { LocalDateTime ldt4 = (LocalDateTime)l; DayOfWeek dayOfWeek = ldt4.getDayOfWeek(); if(dayOfWeek.equals(DayOfWeek.FRIDAY)) { return ldt4.plusDays(3); } else if(dayOfWeek.equals(DayOfWeek.SATURDAY)) { return ldt4.plusDays(2); } else { return ldt4.plusDays(1); } }); System.out.println(ldt5); } // 3、 Duration: 计算两个“时间”之间的间隔 // Period: 计算两个“日期”之间的间隔 @Test public void test4() { LocalDate l1 = LocalDate.of(2022, 5, 17); LocalDate l2 = LocalDate.now(); Period period = Period.between(l1, l2); System.out.println(period); System.out.println(period.getYears()); System.out.println(period.getMonths()); System.out.println(period.getDays()); } @Test public void test3() throws InterruptedException { Instant i1 = Instant.now(); Thread.sleep(1000); Instant i2 = Instant.now(); System.out.println(Duration.between(i1, i2)); System.out.println("----------------------------"); LocalTime l1 = LocalTime.now(); Thread.sleep(1000); LocalTime l2 = LocalTime.now(); System.out.println(Duration.between(l1, l2)); } // 2、Instant :时间戳(以Unix元年:1970年1月1日00:00:00到某个时间之间的毫秒数) @Test public void test2() { Instant i1 = Instant.now(); // 默认获取UTC时区 System.out.println(i1); // 与中国相差八个时区,可设置偏移 OffsetDateTime time = i1.atOffset(ZoneOffset.ofHours(8)); System.out.println(time); // 从 1970-现在 的秒数 long second = i1.getEpochSecond(); System.out.println(second); // 从元年开始计算,这里是+60s Instant i2 = Instant.ofEpochSecond(60); System.out.println(i2); } // 1、LocalDate LocalTime LocalDateTime(前两个的结合体) // 一个会用另外两个也差不多了 @Test public void test1() { // 返回当前年月日时分秒毫秒 LocalDateTime ldt1 = LocalDateTime.now(); System.out.println(ldt1); // 构造日期 LocalDateTime ldt2 = LocalDateTime.of(2023, 5, 18, 20, 2, 20); System.out.println(ldt2); // 加年数 LocalDateTime ldt3 = ldt1.plusYears(2); System.out.println(ldt3); // 减年数 LocalDateTime ldt4 = ldt1.minusYears(2); System.out.println(ldt4); // 取详细信息 System.out.println(ldt1.getYear()); System.out.println(ldt1.getMonthValue()); System.out.println(ldt1.getDayOfMonth()); System.out.println(ldt1.getHour()); System.out.println(ldt1.getMinute()); System.out.println(ldt1.getNano()); }}
public class MyClass { public String getName() { return "father"; }}===========================================================================public interface MyFun { default String getName() { return "hahaha"; }}===========================================================================public interface MyInterface { default String getName() { return "heiheihei"; }}===========================================================================public class SubClass extends MyClass implements MyFun, MyInterface { // 两个接口中都有同名函数时,需要实现方法指定执行哪一个接口中的函数// 当父类中也有同名函数而子类中没有时,默认调用父类函数,忽略接口中的默认函数}===========================================================================public class testDefault { public static void main(String[] args) { SubClass subClass = new SubClass(); System.out.println(subClass.getName()); }}
public class SubClass extends MyClass implements MyFun, MyInterface { // 两个接口中都有同名函数时,需要实现方法指定执行哪一个接口中的函数// 当父类中也有同名函数而子类中没有时,默认调用父类函数,忽略接口中的默认函数 @Override public String getName() { return MyInterface.super.getName(); }}
public interface MyInterface { default String getName() { return "heiheihei"; } public static void show() { System.out.println("展示"); }}==================================================public class testDefault { public static void main(String[] args) { SubClass subClass = new SubClass(); System.out.println(subClass.getName()); // 调用接口中的静态方法 MyInterface.show(); }}
public class testOptional { // 为什么说它方便了空指针异常的调试,因为这里出现空值会报错NoSuchElementException @Test public void test6() { Optional optional = Optional.ofNullable(new Employee("张三", 18, 50000.0, Employee.Status.BUSY));// Optional name = optional.map((e) -> optional.get().getName());// System.out.println(name.get()); Optional name = optional.flatMap(e -> Optional.of(e.getName())); System.out.println(name.get()); } @Test public void test5() { Optional optional = Optional.ofNullable(null); // 如果optional为空,那么返回传进去的默认参数,否则返回optional的参数 Employee employee1 = optional.orElse(new Employee()); System.out.println(employee1); // 使用供给型函数式接口,如果optional为空,那么返回传进去的默认参数,否则返回optional的参数 Employee employee2 = optional.orElseGet(Employee::new); System.out.println(employee2); } @Test public void test4() { Optional optional = Optional.ofNullable(null);// System.out.println(optional.get()); // 报错NoSuchElementException // 安全的做法,判断是否包含值 if(optional.isPresent()) { System.out.println(optional.get()); } } @Test public void test3() { Optional optional = Optional.empty(); System.out.println(optional.get()); // 报错NoSuchElementException } @Test public void test2() { Optional optional = Optional.of(null); // 报错NullPointerException } @Test public void test1() { Optional optional = Optional.of(new Employee()); System.out.println(optional.get()); }}
@Repeatable(MyAnnotaions.class) // 指明容器类@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE, TYPE_PARAMETER})@Retention(RetentionPolicy.RUNTIME)public @interface MyAnnotaion { String value() default "atguigu";}===============================================================================@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE})@Retention(RetentionPolicy.RUNTIME)public @interface MyAnnotaions { MyAnnotaion[] value();}===============================================================================public class TestAnnotaion { @Test public void test1() throws Exception { Class aClass = TestAnnotaion.class; Method method = aClass.getMethod("show"); MyAnnotaion[] annotations = method.getAnnotationsByType(MyAnnotaion.class); for(MyAnnotaion mya: annotations) { System.out.println(mya); } } @MyAnnotaion("world") @MyAnnotaion("hello") public void show(@MyAnnotaion("abc") String abs) { }}
来源地址:https://blog.csdn.net/m0_62946761/article/details/130753016
--结束END--
本文标题: Java——JDK1.8新特性
本文链接: https://lsjlt.com/news/415499.html(转载时请注明来源链接)
有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341
2024-04-01
2024-04-03
2024-04-03
2024-01-21
2024-01-21
2024-01-21
2024-01-21
2023-12-23
回答
回答
回答
回答
回答
回答
回答
回答
回答
回答
0