1. 动态代理

  在一个方法前后加内容,最简单直观的方法就是直接在代码上加内容(如数据库中的事务),但这样写不够灵活,并且代码可维护性差,所以就需要引入动态代理

1.1 静态代理实现  

  在讲动态代理之前,需要先讲下静态代理,静态代理就是通过proxy持有realObject的引用,并进行一层封装,从而达到增强的效果

需求:在target中的test方法中加上一些内容(打印结果前后加上日志内容)

a  简单直观的方法

接口

public interface InterfaceA {
public void test();
}

Target类(在上面直接加内容)

public class Target implements InterfaceA{
@Override
public void test() {
System.out.println("日志开始"); //方法前加内容
System.out.println("这世界会好吗");
System.out.println("日志结束"); //方法后加内容
}
}

这样写不够好,破坏了target这个类,万一其他地方需要调用这个方法有的地方需要这内容,有的地方不需要,但又不想要这个日志内容,这样就显得多余了,所以,该怎么解决这个问题呢?

解决方法:定义一个单独的类来实现这样的需求,这样一个类我们称为代理

代理类(Proxy)

public class Proxy implements InterfaceA{
Target t = new Target(); //目标对象
@Override
public void test() {
System.out.println("日志开始"); //增强
t.test();
System.out.println("日至结束");
}
}

测试类

public class ProxyTest {
public static void main(String[] args) {
Proxy p = new Proxy();
p.test();
}
}

当目标类中的某个方法需要加一些特定的内容(如事务),就可以在代理类中创建目标类的对象并在相应方法加上想要的内容(如事务),在代理类自身的方法内调用相应的方法即可,这样以来就实现了在Target类某个方法灵活加内容的需求,但是其也有一个问题,就是当Target类中有成百上千的方法,并且每个方法都需要加上内容,这时候代理类写起来会很麻烦,这个时候就需要动态代理

1.2 动态代理的实现

接口

1.3 java8新特性

新特性概览:
  1. 接口中的默认方法与静态方法(即接口中不是只能有抽象方法了)
  2. Lambda 表达式
  3. 集合中的Stream
  4. DateApi
  5. 其他
    String: join
    String str = String.join(",", "a", "b", "c");

1.3.1. lambda表达式

1. 使用lambda表达式的前提:

  具有函数式接口(只包含一个抽象方法的接口(SAM),其他实现了的方法可以有多个

2. 格式: 

  lambda 表达式实际上就是代码块的传递的实现。其语法结构如下:
  (parameters) -> expression 或者(parameters) -> {statements;}

注意事项:

  a. 括号里的参数可以省略其类型,编译器会根据上下文来推导参数的类型,也可以显式的指定参数类型,如果没有参数,括号内可以为空

  b. 方法体,如果有多行功能语句用大括号括起来,如果只有一行功能语句则可以省略大括号

  c. 可替代匿名内部类

方法的引用(不太懂):

方法引用,方法引用是lambda 表达式的一种简写形式。如果lambda 表达式只是调用一个特定的已经存在的方法,则可以使用方法引用。

使用“::”操作符将方法名和对象或类的名字分隔开来。以下是四种使用情况:
  对象::实例方法
  类::静态方法
  类::实例方法
  类::new

Arrays.sort(str, (o1,o2)->o1.compareToIgnoreCase(o2));
Arrays.sort(strings, String::compareToIgnoreCase);

案例1:以线程为例

正常开启一个线程的代码如下:

public class LambdaDemo {
public static void main(String[] args) {
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("哈哈");
}
}).start();;
}
}

分析:Thread里面一定是runnable对象,所以此可以省略掉,此外,runnable里面只有run方法,所以也可以省略,简化后的代码就变成如下:

public class LambdaDemo {
public static void main(String[] args) {
new Thread(() { // 此处的小括号不能省略,有可能要传参数
System.out.println("哈哈");
}).start();;
}
}

如果实现的抽象方法只有一行,那么大括号也可以省略,用lambda得到的代码如下

public class LambdaDemo {
public static void main(String[] args) {
new Thread(()-> System.out.println("哈哈")).start();;
}
}

lambda表达式只关注接口中方法的参数,以及方法是怎么实现的

案例2:list的降序排序

未使用lambda表达式

public class LambdaDemo {
public static void main(String[] args) {
List<Integer> list = Arrays.asList(1,3,6,12,14,27);
Collections.sort(list, new Comparator<Integer>() { //实现降序排序
@Override
public int compare(Integer o1, Integer o2) {
// TODO Auto-generated method stub
return o2-o1;
}
});
}
}

lambda表达式

public class LambdaDemo {
public static void main(String[] args) {
List<Integer> list = Arrays.asList(1,3,6,12,14,27);
Collections.sort(list, (o1,o2)-> o2-o1);
}
  // 遍历此list
  list.forEach((t)->System.out.print(t))
  // 将上面遍历进一步改为方法引用
  list.forEach(System.out::print)
}

此处o1,o2的类型可以省略,如上,编译器会根据上下文自动推断出其类型,此处为Integer类型

案例3:map的遍历(常规方法有三种,见以前笔记)

lambda形式

public class LambdaDemo1 {
public static void main(String[] args) {
HashMap<Integer, String> map = new HashMap<>();
map.put(1, "a");
map.put(2, "b");
map.put(3, "c");
map.put(4, "d");
map.forEach((k,v)->System.out.println(k+":"+v));
}
}

1.3.2 stream

Stream是Java 8 提供的高效操作集合类(Collection)数据的API

1. 如何获取Stream

(1)使用集合创建

public static Stream<Integer> getStream() {
List<Integer> list = Arrays.asList(1,2,3,5,32,24);
return list.stream();
}

(2)使用数组创建

String[] arr = new String[] {"James","Wade","Kobe","Jardon"};
return Arrays.stream(arr);

(3)使用value创建

return Stream.of("哈哈","呵呵","嘿嘿"); 

(4)使用iterate创建

return Stream.iterate("h", n->n+5).limit(10);

(5)使用generate

return Stream.generate(Math::random).limit(20);

2. Stream中常用操作

(1)forEach:循环输出

(2)filter:帅选

(3)limit:限制取多少个

(4)sorted:

(5)join:将Stream转成字符串

public class StreamDemo1 {
public static void main(String[] args) {
Stream<String> s4 = Stream.of("I","Love","u");
String s8 = s4.collect(Collectors.joining(" "));
System.out.println(s8);//I Love u
Stream<String> s5 = Stream.of("I","Love","u");
String s9 = s5.collect(Collectors.joining(",","{","}"));
System.out.println(s9);//{I,Love,u}
}
}

(6)distinct:去重

Stream.of("aa","bb","aa").distinct().forEach(System.out::print);//aabb

(7)map:对每一个元素进行操作

(8)reduce:归并

(9)collection:收集(将流转成集合)

1.3.3DateApi

  jdk8中这个特性使得日期和时间可以分离开(以前的date是连在一起的),其通过三个类实现,如下

public class DateApiDemo {
public static void main(String[] args) {
LocalDateTime now = LocalDateTime.now();//当前时间(日期和时间)
System.out.println(now); //2019-09-02T16:59:29.862366800
LocalDate now1 = LocalDate.now();//日期
System.out.println(now1);//2019-09-02
LocalTime now2 = LocalTime.now();//时间
System.out.println(now2);//17:03:32.698811500
}
}

把LocalDateTime转成想要的格式(使用DateTimeFormatter)

DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
System.out.println(now.format(dtf)); // 2019-09-02 17:12:36

把字符串转成LocalDateTime

LocalDateTime ldt1 = LocalDateTime.parse("2019-09-02 17:12:36",dtf);
System.out.println(ldt1);//2019-09-02T17:12:36

此外,此新特性可以得到单独的年,月(中文和英文),日(某个月的第几天,以及某年的第几天)

System.out.println(now.getYear());//2019    获取年份
System.out.println(now.getMonth());//SEPTEMBER 获取英文的月份
System.out.println(now.getMonthValue());//9   获取中文的月数
System.out.println(now.getDayOfMonth());//2 获取该时间中天数属于该时间的月中的第几天
System.out.println(now.getDayOfYear());//245 获取该时间中天数属于该时间的年中的第几天

将确定的时间以单独的年、月、日、小时等来修改来,其形式见下例:

// 修改年份
System.out.println(now); // 2019-09-02T19:30:51.234745600
LocalDateTime d2 = now.withYear(2020);
System.out.println(d2); // 2020-09-02T19:30:51.234745600
//修改月份
LocalDateTime d3 = now.withMonth(11);
System.out.println(d3); // 2019-11-02T19:30:51.234745600

零基础学习java------21---------动态代理,java8新特性(lambda, stream,DateApi)的更多相关文章

  1. Java基础学习总结(55)——java8新特性:stream

    java作为开发语言中的元老已经度过了很多年,最新的java8为我们带来了一些新特性,这些特性可以在以后的工作中为我们的开发提供更多的便捷,现在就让我们看看最新的函数式编程风格怎么在实际的开发中使用. ...

  2. Java8 新特性 Lambda & Stream API

    目录 Lambda & Stream API 1 Lambda表达式 1.1 为什么要使用lambda表达式 1.2 Lambda表达式语法 1.3 函数式接口 1.3.1 什么是函数式接口? ...

  3. 音乐出身的妹纸,零基础学习JAVA靠谱么

    问:表示音乐出身的妹纸一枚  某一天突然觉得身边认识的是一群程序员   突然想 要不要也去试试... 众好友都觉得我该去做个老师,可是我怕我会误人子弟,祸害祖国下一代..... 要不要 要不要 学Ja ...

  4. 总结了零基础学习Java编程语言的几个基础知识要点

    很多Java编程初学者在刚接触Java语言程序的时候,不知道该学习掌握哪些必要的基础知识.本文总结了零基础学习Java编程语言的几个基础知识要点. 1先了解什么是Java的四个方面   初学者先弄清这 ...

  5. java8新特性——Lambda表达式

    上文中简单介绍了一下java8得一些新特性,与优点,也是为本次学习java8新特性制定一个学习的方向,后面几篇会根据上文中得新特性一一展开学习.本文就从java8新特性中比较重要的Lambda表达式开 ...

  6. Java8新特性-Lambda表达式是什么?

    目录 前言 匿名内部类 函数式接口 和 Lambda表达式语法 实现函数式接口并使用Lambda表达式: 所以Lambda表达式是什么? 实战应用 总结 前言 Java8新特性-Lambda表达式,好 ...

  7. 乐字节-Java8新特性之Stream流(上)

    上一篇文章,小乐给大家介绍了<Java8新特性之方法引用>,下面接下来小乐将会给大家介绍Java8新特性之Stream,称之为流,本篇文章为上半部分. 1.什么是流? Java Se中对于 ...

  8. 乐字节-Java8新特性-Lambda表达式

    上一篇文章我们了解了Java8新特性-接口默认方法,接下来我们聊一聊Java8新特性之Lambda表达式. Lambda表达式(也称为闭包),它允许我们将函数当成参数传递给某个方法,或者把代码本身当作 ...

  9. 【Java8新特性】- Stream流

    Java8新特性 - Stream流的应用 生命不息,写作不止 继续踏上学习之路,学之分享笔记 总有一天我也能像各位大佬一样 一个有梦有戏的人 @怒放吧德德 分享学习心得,欢迎指正,大家一起学习成长! ...

  10. Java8 新特性之Stream API

    1. Stream 概述 Stream 是Java8中处理集合的关键抽象概念,可以对集合执行非常复杂的查找,过滤和映射数据等操作; 使用 Stream API 对集合数据进行操作,就类似于使用 SQL ...

随机推荐

  1. Atcoder 题目泛做

    我思维越来越菜了,这样下去感觉要退役了. 听说Atcoder的题练思维?那就试着做一做吧. 坚持每天一两道吧.(很有可能咕掉.) AGC036 官方题解 ---A-Triangle          ...

  2. 前端面试手写代码——JS数组去重

    目录 1 测试用例 2 JS 数组去重4大类型 2.1 元素比较型 2.1.1 双层 for 循环逐一比较(es5常用) 2.1.2 排序相邻比较 2.2 查找元素位置型 2.2.1 indexOf ...

  3. js 在浏览器中的event loop事件队列

    目录 前言 认识一个栈两个队列 执行过程 异步任务怎么分配 简单例子 难一点的例子 前言 以下内容是js在浏览器中的事件队列执行,与在nodejs中有所区别,请注意. 都说js是单线程的,不过它本身其 ...

  4. 【Python+postman接口自动化测试】(2)什么是接口?

    接口的概念 接口又称API(Application Programming Interface,应用程序编程接口),是一些预先定义的函数,目的是提供应用程序与开发人员基于某软件或硬件得以访问一组例程的 ...

  5. Win10-更改c盘下的用户文件夹名

    如果你是win10家庭版,请先升级成专业版 win10家庭版升级到win10专业版 修改用户名称

  6. dedecms被挂马排毒的过程

    又经历了一次dedecms被挂马排毒的过程,排毒过程在这里跟大家分享一下. 挂马之后,网站的表现形式: 直接访问网站没有任何问题,从百度搜索的关键词访问网站,就跳转到另外一个网站. 根据我原来的排毒经 ...

  7. [nfls338]基本字典子串

    1.前置知识 以下数字未特殊说明,取值范围均与$N$​​​取交 以下字符串未特殊说明,下标均从1开始,且均为非空串,复杂度中的$n$​​​指字符串长度 周期和border 对于非空集合$S$,定义$\ ...

  8. [atAGC045B]01 Unbalanced

    将0变为-1后求前缀和,那么$s$的价值即为最大的前缀和-最小的前缀和(特别的,空前缀的前缀和为0) 令$f(x)$表示当最大的前缀和不大于$x$时,最小的前缀和最大是多少,答案即为$\min_{x} ...

  9. [atAGC046F]Forbidden Tournament

    称满足第1个条件的图为竞赛图,先来分析竞赛图 结论1:竞赛图点集上的导出子图也为竞赛图(证明略) 结论2:对于一张竞赛图,若不含有3元环,则该图为DAG 证明:反证法,若其不为DAG,设最小的简单环为 ...

  10. 描述高频题之队列&栈

    栈和队列 全文概览 基础知识 栈 栈是一种先进后出的数据结构.这里有一个非常典型的例子,就是堆叠盘子.我们在放盘子的时候,只能从下往上一个一个的放:在取的时候,只能从上往下一个一个取,不能从中间随意取 ...