精华内容
下载资源
问答
  • Java中lambda表达式的基本语法包含三个部分: 1、参数 2、-> 3、功能体 [1] 当只用一个参数,可以不需要括号 ()。 然而,这是一个特例。 [2] 正常情况使用括号 () 包裹多个参数。 为了保持一致性,也可以使用括号...

    1、lambda语法

    Java中lambda表达式的基本语法包含三个部分:
    1、参数
    2、-> // 一定有
    3、功能体
    [1] 当只有一个参数,可以不需要括号 ()。 然而,这是一个特例。
    [2] 正常情况使用括号 () 包裹多个参数。 为了保持一致性,也可以使用括号 () 包裹单个参数,虽然这种情况并不常见。
    [3] 如果没有参数,则必须使用括号 () 表示空参数列表。
    [4] 如果功能体是单行,表达式结果自动成为Lambda表达式返回的结果
    [5] 如果功能体有多行,必须使用{}包含,必须使用return表达返回结果
    Lambda比匿名内部类更加易读,我们应该多多使用。

    2、实际使用

    List转Map

    Map<String, String> collect = list.stream().collect(Collectors.toMap(i -> i, i -> i));

    lambda就是一个被结构化的功能,可以被函数传递,这样能使函数的功能更加强大和语法简介。

    在Java集合的使用中,充斥着大量lambda用法,使得用简单的代码就实现了复杂的功能。

    Java集合的stream()返回的是Stream<T>类型的具体实现,这个实现包含存储的数据和各种操作这些数据的能力,所以你能看到sorted()、filter()、distinct()、collect()等方法。

    这里我们关注collect()方法,<R, A> R collect(Collector<? super T, A, R> collector);方法声明就很厉害,

    R: the type of the result

    A: the intermediate accumulation type of the {@code Collector} 中间累计类型of the Collector

    R: 收减操作结果类型

    其实关键还是

    public interface Collector<T, A, R> {} 收集操作也即reduce收减操作

     @param <T> the type of input elements to the reduction operation 输入元素的类型
     @param <A> the mutable accumulation type of the reduction operation (often
        hidden as an implementation detail) 可变中间类型
     @param <R> the result type of the reduction operation 收缩操作的结果类型

    下面是工具类Collectors的toMap()方法

        public static <T, K, U>
        Collector<T, ?, Map<K,U>> toMap(Function<? super T, ? extends K> keyMapper,
                                        Function<? super T, ? extends U> valueMapper) {
            return new CollectorImpl<>(HashMap::new,
                                       uniqKeysMapAccumulator(keyMapper, valueMapper),
                                       uniqKeysMapMerger(),
                                       CH_ID);
        }

    其中toMap()方法的2个参数都是函数接口的子类型,也就是说可以使用lambda表达式来进行实参传递,其中T是原始输入数据的类型,K是map键的类型,U是map值的类型,Function的2个类型参数作用分别为输入类型和返回类型,所以,2个lambda表达式的作用是映射得到map的key和value,lambda表达式的输入都是输入元素,Collectors.toMap(i -> i, i -> i) 指定了从输入元素到map的key和value的映射。

    3、lambda捕获的变量为什么只能用final修饰?

    Java8语言上的lambda表达式只实现了capture-by-value(值捕获),也就是说它捕获的局部变量都会拷贝一份到lambda表达式的实体里,然后在lambda表达式里要变也只能变自己的那份拷贝而无法影响外部原本的变量;但是Java语言的设计者又要挂牌坊不明说自己是capture-by-value,为了以后语言能进一步扩展成支持capture-by-reference留下后路,所以现在干脆不允许向捕获的变量赋值,而且可以捕获的也只有“效果上不可变”(effectively final)的参数/局部变量。

    但是Java只是不允许改变被lambda表达式捕获的变量,并没有限制这些变量所指向的对象的状态能不能变。要从lambda表达式向外传值的常见workaround之一就是用长度为1的数组:

    String[] a = new String[1];
    ... ( () -> a[0] = "a" );
    return a[0];

     

     

    展开全文
  • 1. 一共17位只包含数字和大写字母 2. 不包含英文字母“I”、“O”、“Q” 3. 第13到17位为数字 4. 任意连续5位不允许相同 以上条件同时满足
  • JAVA三元表达式详解

    万次阅读 2018-12-04 15:01:28
    三元表达式即 boolean?true:false 这是表达式是语法 例句一个demo: int new1=10; int new2=20; int new3=null; new3 = new2&gt;new1?30:0 这句三元表达式的意思是 当new2&gt;new1=true:的时候...

    三元表达式即

    boolean?true:false 

    这是表达式是语法

     

    例句一个demo:

    int new1=10;

    int new2=20;

    int new3=null;

    new3 = new2>new1?30:0

    这句三元表达式的意思是

    当new2>new1=true:的时候 new3=30

    当new2>new1=false:的时候 new3=0

    可以根据你的个人想法去运用这三元表达式  用得好可构建复杂表达结果

     

    以上如有问题可评论 如有错误欢迎指教  我看到立马回答

    请不要私自转载 !!!

    展开全文
  • Java Lambda 表达式学习笔记 Java Lambda 表达式Java 8 引入的一个新的功能,可以说是模拟函数式编程的一个语法糖,类似于 Javascript 中的闭包,但又有些不同,主要目的是提供一个函数化的语法来简化我们的编码...

    Java Lambda 表达式学习笔记

    Java Lambda 表达式是 Java 8 引入的一个新的功能,可以说是模拟函数式编程的一个语法糖,类似于 Javascript 中的闭包,但又有些不同,主要目的是提供一个函数化的语法来简化我们的编码。

    Lambda 基本语法

    Lambda 的基本结构为 (arguments) -> body,有如下几种情况:

    • 参数类型可推导时,不需要指定类型,如 (a) -> System.out.println(a)
    • 当只有一个参数且类型可推导时,不强制写 (), 如 a -> System.out.println(a)
    • 参数指定类型时,必须有括号,如 (int a) -> System.out.println(a)
    • 参数可以为空,如 () -> System.out.println(“hello”)
    • body 需要用 {} 包含语句,当只有一条语句时 {} 可省略

    常见的写法如下:

    (a) -> a * a
    
    (int a, int b) -> a + b
    
    (a, b) -> {return a - b;}
    
    () -> System.out.println(Thread.currentThread().getId())

    函数式接口 FunctionalInterface

    概念

    Java Lambda 表达式以函数式接口为基础。什么是函数式接口(FunctionalInterface)? 简单说来就是只有一个方法(函数)的接口,这类接口的目的是为了一个单一的操作,也就相当于一个单一的函数了。常见的接口如:Runnable, Comparator 都是函数式接口,并且都标注了注解 @FunctionalInterface 。

    举例

    以 Thread 为例说明很容易理解。Runnable 接口是我们线程编程时常用的一个接口,就包含一个方法 void run(),这个方法就是线程的运行逻辑。按照以前的语法,我们新建线程一般要用到 Runnable 的匿名类,如下:

    new Thread(new Runnable() {
    
        @Override
    
        public void run() {
    
            System.out.println(Thread.currentThread().getId());
    
        }
    
    
    
    }).start();

    如果写多了,是不是很无聊,而基于 Lambda 的写法则变得简洁明了,如下:

    new Thread(() -> System.out.println(Thread.currentThread().getId())).start();

    注意 Thread 的参数,Runnable 的匿名实现就通过一句就实现了出来,写成下面的更好理解

    Runnable r = () -> System.out.println(Thread.currentThread().getId());new Thread(r).start();

    当然 Lambda 的目的不仅仅是写起来简洁,更高层次的目的等体会到了再总结。

    再看一个比较器的例子,按照传统的写法,如下:

    Integer[] a = {1, 8, 3, 9, 2, 0, 5};
    Arrays.sort(a, new Comparator<Integer>() {
        @Override
        public int compare(Integer o1, Integer o2) {
            return o1 - o2;
        }
    });

    Lambda 表达式写法如下:

    Integer[] a = {1, 8, 3, 9, 2, 0, 5};
    Arrays.sort(a, (o1, o2) -> o1 - o2);

    JDK中的函数式接口

    为了现有的类库能够直接使用 Lambda 表达式,Java 8 以前存在一些接口已经被标注为函数式接口的:

    • java.lang.Runnable
      java.util.Comparator
      java.util.concurrent.Callable
      java.io.FileFilter
      java.security.PrivilegedAction
      java.beans.PropertyChangeListener

       

    Java 8 中更是新增加了一个包 java.util.function,带来了常用的函数式接口:

    Function<T, R> - 函数:输入 T 输出 R
    BiFunction<T, U, R> - 函数:输入 T 和 U 输出 R 对象
    Predicate<T> - 断言/判断:输入 T 输出 boolean
    BiPredicate<T, U> - 断言/判断:输入 T 和 U 输出 boolean
    Supplier<T> - 生产者:无输入,输出 T
    Consumer<T> - 消费者:输入 T,无输出
    BiConsumer<T, U> - 消费者:输入 T 和 U 无输出
    UnaryOperator<T> - 单元运算:输入 T 输出 T
    BinaryOperator<T> - 二元运算:输入 T 和 T 输出 T

    另外还对基本类型的处理增加了更加具体的函数是接口,包括:

    BooleanSupplier, DoubleBinaryOperator, DoubleConsumer, DoubleFunction<R>, DoublePredicate, DoubleSupplier, DoubleToIntFunction, DoubleToLongFunction, DoubleUnaryOperator, IntBinaryOperator, IntConsumer, IntFunction<R>, IntPredicate, IntSupplier, IntToDoubleFunction, IntToLongFunction, IntUnaryOperator, LongBinaryOperator, LongConsumer,LongFunction<R>, LongPredicate, LongSupplier, LongToDoubleFunction,LongToIntFunction, LongUnaryOperator, ToDoubleBiFunction<T, U>, ToDoubleFunction<T>,ToIntBiFunction<T, U>, ToIntFunction<T>, ToLongBiFunction<T, U>, ToLongFunction<T> 。

    结合上面的函数式接口,对这些基本类型的函数式接口通过类名就能一眼看出接口的作用。

    创建函数式接口

    有时候我们需要自己实现一个函数式接口,做法也很简单,首先你要保证此接口只能有一个函数操作,然后在接口类型上标注注解 @FunctionalInterface 即可。

    类型推导

    类型推导是 Lambda 表达式的基础,类型推导的过程就是 Lambda 表达式的编译过程。以下面的代码为例:

    Function<String, Integer> strToInt = str -> Integer.parseInt(str);

    编译期间,我理解的类型推导的过程如下:

    1. 先确定目标类型 Function
    2. Function 作为函数式接口,其方法签名为:Integer apply(String t)
    3. 检测 str -> Integer.parseInt(str) 是否与方法签名匹配(方法的参数类型、个数、顺序 和返回值类型)
    4. 如果不匹配,则报编译错误

    这里的目标类型是关键,通过目标类型获取方法签名,然后和 Lambda 表达式做出对比。

    方法引用

    方法引用(Method Reference)的基础同样是函数式接口,可以直接作为函数式接口的实现,与 Lambda 表达式有相同的作用,同样依赖于类型推导。方法引用可以看作是只调用一个方法的 Lambda 表达式的简化。

    方法引用的语法为: Type::methodName 或者 instanceName::methodName , 构造函数对应的 methodName 为 new。

    例如上面曾用到例子:

    Function<String, Integer> strToInt = str -> Integer.parseInt(str);

    对应的方法引用的写法为

    Function<String, Integer> strToInt = Integer::parseInt;

    根据方法的类型,方法引用主要分为一下几种类型,构造方法引用、静态方法引用、实例上实例方法引用、类型上实例方法引用等

    构造方法引用

    语法为: Type::new 。 如下面的函数为了将字符串转为数组

    方法引用写法

    Function<String, Integer> strToInt = Integer::new;

    Lambda 写法

    Function<String, Integer> strToInt = str -> new Integer(str);

    传统写法

    Function<String, Integer> strToInt = new Function<String, Integer>() {
        @Override
        public Integer apply(String str) {
            return new Integer(str);
        }
    };

    数组构造方法引用

    语法为: Type[]::new 。如下面的函数为了构造一个指定长度的字符串数组

    方法引用写法

    Function<Integer, String[]> fixedArray = String[]::new;

    方法引用写法

    Function<Integer, String[]> fixedArray = length -> new String[length];

    传统写法

    Function<Integer, String[]> fixedArray = new Function<Integer, String[]>() {
        @Override
        public String[] apply(Integer length) {
            return new String[length];
        }
    };

    静态方法引用

    语法为: Type::new 。 如下面的函数同样为了将字符串转为数组

    方法引用写法

    Function<String, Integer> strToInt = Integer::parseInt;

    Lambda 写法

    Function<String, Integer> strToInt = str -> Integer.parseInt(str);

    传统写法

    Function<String, Integer> strToInt = new Function<String, Integer>() {
        @Override
        public Integer apply(String str) {
            return Integer.parseInt(str);
        }
    };

    实例上实例方法引用

    语法为: instanceName::methodName 。如下面的判断函数用来判断给定的姓名是否在列表中存在

    List<String> names = Arrays.asList(new String[]{"张三", "李四", "王五"});
    
    Predicate<String> checkNameExists = names::contains;
    
    System.out.println(checkNameExists.test("张三"));
    
    System.out.println(checkNameExists.test("张四"));

    类型上实例方法引用

    语法为: Type::methodName 。运行时引用是指上下文中的对象,如下面的函数来返回字符串的长度

    Function<String, Integer> calcStrLength = String::length;
    
    System.out.println(calcStrLength.apply("张三"));
    
    List<String> names = Arrays.asList(new String[]{"zhangsan", "lisi", "wangwu"});
    
    names.stream().map(String::length).forEach(System.out::println);

    又比如下面的函数已指定的分隔符分割字符串为数组

    BiFunction<String, String, String[]> split = String::split;
    
    String[] names = split.apply("zhangsan,lisi,wangwu", ",");
    
    System.out.println(Arrays.toString(names));

    Stream 对象

    概念

    什么是 Stream ? 这里的 Stream 不同于 io 中的 InputStream 和 OutputStream,Stream 位于包 java.util.stream 中, 也是 java 8 新加入的,Stream 只的是一组支持串行并行聚合操作的元素,可以理解为集合或者迭代器的增强版。什么是聚合操作?简单举例来说常见的有平均值、最大值、最小值、总和、排序、过滤等。

    Stream 的几个特征:

    • 单次处理。一次处理结束后,当前Stream就关闭了。
    • 支持并行操作

    常见的获取 Stream 的方式

          从集合中获取

    • Collection.stream();
      Collection.parallelStream();

      静态工厂

    • Arrays.stream(array)
      Stream.of(T …)
      IntStream.range()

       

    这里只对 Stream 做简单的介绍,下面会有具体的应用。要说 Stream 与 Lambda 表达式有什么关系,其实并没有什么特别紧密的关系,只是 Lambda 表达式极大的方便了 Stream 的使用。如果没有 Lambda 表达式,使用 Stream 的过程中会产生大量的匿名类,非常别扭。

    举例

    以下的demo依赖于 Employee 对象,以及由 Employee 对象组成的 List 对象。

    public class Employee {
    
    
    
        private String name;
    
        private String sex;
    
        private int age;
    
    
    
        public Employee(String name, String sex, int age) {
    
            super();
    
            this.name = name;
    
            this.sex = sex;
    
            this.age = age;
    
        }
    
        public String getName() {
    
            return name;
    
        }
    
    
    
        public String getSex() {
    
            return sex;
    
        }
    
        public int getAge() {
    
            return age;
    
        }
    
        @Override
    
        public String toString() {
    
            StringBuilder builder = new StringBuilder();
    
            builder.append("Employee {name=").append(name).append(", sex=").append(sex).append(", age=").append(age)
    
                    .append("}");
    
            return builder.toString();
    
        }
    
    }
    
    List<Employee> employees = new ArrayList<>();
    
    employees.add(new Employee("张三", "男", 25));
    
    employees.add(new Employee("李四", "女", 24));
    
    employees.add(new Employee("王五", "女", 23));
    
    employees.add(new Employee("周六", "男", 22));
    
    employees.add(new Employee("孙七", "女", 21));
    
    employees.add(new Employee("刘八", "男", 20));

    打印所有员工

    Collection 提供了 forEach 方法,供我们逐个操作单个对象。

    employees.forEach(e -> System.out.println(e));
    
    或者
    
    employees.stream().forEach(e -> System.out.println(e));

    按年龄排序

    Collections.sort(employees, (e1, e2) -> e1.getAge() - e2.getAge());
    
    employees.forEach(e -> System.out.println(e));
    
    或者
    
    employees.stream().sorted((e1, e2) -> e1.getAge() - e2.getAge()).forEach(e -> System.out.println(e));

    打印年龄最大的女员工

    max/min 返回指定排序条件下最大/最小的元素

    Employee maxAgeFemaleEmployee = employees.stream()
            .filter(e -> "女".equals(e.getSex()))
            .max((e1, e2) -> e1.getAge() - e2.getAge())
            .get();
    System.out.println(maxAgeFemaleEmployee);

    打印出年龄大于20 的男员工

    filter 可以过滤出符合条件的元素

    employees.stream()
            .filter(e -> e.getAge() > 20 && "男".equals(e.getSex()))
            .forEach(e -> System.out.println(e));

    打印出年龄最大的2名男员工

    limit 方法截取有限的元素

    employees.stream()
            .filter(e -> "男".equals(e.getSex()))
            .sorted((e1, e2) -> e2.getAge() - e1.getAge())
            .limit(2)
            .forEach(e -> System.out.println(e));

    打印出所有男员工的姓名,使用 , 分隔

    map 将 Stream 中所有元素的执行给定的函数后返回值组成新的 Stream

    String maleEmployeesNames = employees.stream()
            .map(e -> e.getName())
            .collect(Collectors.joining(","));
    System.out.println(maleEmployeesNames);

    统计信息

    IntSummaryStatistics, DoubleSummaryStatistics, LongSummaryStatistics 包含了 Stream 中的汇总数据。
    IntSummaryStatistics stat = employees.stream()
            .mapToInt(Employee::getAge).summaryStatistics();
    System.out.println("员工总数:" + stat.getCount());
    System.out.println("最高年龄:" + stat.getMax());
    System.out.println("最小年龄:" + stat.getMin());
    System.out.println("平均年龄:" + stat.getAverage());

    总结

    Lambda 表达式确实可以减少很多代码,能提高生产力,当然也有弊端,就是复杂的表达式可读性会比较差,也可能是还不是很习惯的缘故吧,如果习惯了,相信会喜欢上的。凡事都有两面性,就看我们如何去平衡这其中的利弊了,尤其是在一个团队中。

     

    展开全文
  • 切入点的表达式 execution(void cn.cdut.spring.demo.UserServiceImpl.saveUser(java.lang.String,java.lang.String)) 表示:无返回类型,cn.cdut.spring.demo包中的UserServiceImpl类,... 表达式写法 exe...

    切入点的表达式


    execution(void cn.cdut.spring.demo.UserServiceImpl.saveUser(java.lang.String,java.lang.String))

    • 表示:无返回类型,cn.cdut.spring.demo包中的UserServiceImpl类,类中的saveUser方法,参数2个,都是String类型

    表达式的写法

    execution(modifiers-pattern? (非必填项)--<访问修饰符>?
              ret-type-pattern (必填项)--<返回类型>
              declaring-type-pattern? (非必填项)
              name-pattern(param-pattern)(必填项)--<方法名>(<参数>)
              throws-pattern?(非必填项)<异常>?

    一共有5个参数
    其中的?表示非必填项

    文档中写的:
    除了返回类型模式(上面代码片断中的ret-type-pattern),名字模式和参数模式以外, 所有的部分都是可选的。
    返回类型模式决定了方法的返回类型必须依次匹配一个连接点。 你会使用的最频繁的返回类型模式是*,它代表了匹配任意的返回类型。
    一个全限定的类型名将只会匹配返回给定类型的方法。名字模式匹配的是方法名。 你可以使用*通配符作为所有或者部分命名模式。
    参数模式稍微有点复杂:()匹配了一个不接受任何参数的方法, 而(..)匹配了一个接受任意数量参数的方法(零或者更多)。
    模式()匹配了一个接受一个任何类型的参数的方法。 模式(,String)匹配了一个接受两个参数的方法,第一个可以是任意类型, 第二个则必须是String类型。更多的信息请参阅AspectJ编程指南中 语言语义的部分。

    1:modifiers-pattern? (非必填项):表示方法的修饰符


    execution(public void cn.cdut.spring.demo.UserServiceImpl.saveUser(java.lang.String,java.lang.String))

    • 表示:共有方法,无返回类型,cn.itcast.spring.demo包中的UserServiceImpl类,类中的saveUser方法,参数2个,都是String类型


    execution(private void cn.cdut.spring.demo.UserServiceImpl.saveUser(java.lang.String,java.lang.String))

    • 表示:私有方法,无返回类型,cn.cdut.spring.demo包中的UserServiceImpl类,类中的saveUser方法,参数2个,都是String类型

    2:ret-type-pattern (必填项):表示方法的返回类型


    execution(void cn.cdut.spring.demo.UserServiceImpl.saveUser(java.lang.String,java.lang.String))

    • 表示:无返回类型,cn.cdut.spring.demo包中的UserServiceImpl类,类中的saveUser方法,参数2个,都是String类型


    execution(java.lang.String cn.cdut.spring.demo.UserServiceImpl.saveUser(java.lang.String,java.lang.String))

    • 表示:返回类型String类型,cn.cdut.spring.demo包中的UserServiceImpl类,类中的saveUser方法,参数2个,都是String类型


    execution(* cn.cdut.spring.demo.UserServiceImpl.saveUser(java.lang.String,java.lang.String))

    • 表示:返回类型任意,cn.cdut.spring.demo包中的UserServiceImpl类,类中的saveUser方法,参数2个,都是String类型

    3:declaring-type-pattern? (非必填项):表示包,或者子包的,或者类的修饰符


    execution(* cn.cdut.spring.demo.UserServiceImpl.saveUser(java.lang.String,java.lang.String))

    • 表示返回类型任意,cn.cdut.spring.demo包中的UserServiceImpl类,类中的saveUser方法,参数2个,都是String类型


    execution(* cn.cdut.spring.*.UserServiceImpl.saveUser(java.lang.String,java.lang.String))

    • 表示返回类型任意,cn.cdut.spring包中的所有子包,包中UserServiceImpl类,类中的saveUser方法,参数2个,都是String类型


    execution(* cn.cdut.spring.*.saveUser(java.lang.String,java.lang.String))

    • 表示返回类型任意,cn.cdut.spring包中的所有类,类中的saveUser方法,参数2个,都是String类型


    execution(* cn.cdut.spring..*.saveUser(java.lang.String,java.lang.String))

    • 表示返回类型任意,cn.cdut.spring包中及其子包中的所有类,类中的saveUser方法,参数2个,都是String类型


    execution(* *.saveUser(java.lang.String,java.lang.String))

    • 表示返回类型任意,所有包中的所有类,类中的saveUser方法,参数2个,都是String类型


    execution(* saveUser(java.lang.String,java.lang.String))

    • 表示返回类型任意,所有包中的所有类,类中的saveUser方法,参数2个,都是String类型

    4:name-pattern(param-pattern)(必填项):方法的名称(方法的参数)

    (1)方法名称


    execution(* cn.cdut.spring.demo.UserServiceImpl.saveUser(java.lang.String,java.lang.String))

    • 表示返回类型任意,cn.cdut.spring.demo包中的UserServiceImpl类,类中的saveUser方法,参数2个,都是String类型


    execution(* cn.cdut.spring.demo.UserServiceImpl.save*(java.lang.String,java.lang.String))

    • 表示返回类型任意,cn.cdut.spring.demo包中的UserServiceImpl类,类中的以save开头的方法,参数2个,都是String类型


    execution(* cn.cdut.spring.demo.UserServiceImpl.*(java.lang.String,java.lang.String))

    • 表示返回类型任意,cn.cdut.spring.demo包中的UserServiceImpl类,类中的所有方法,参数2个,都是String类型

      (2)方法的参数(必填项)


    execution(* cn.itcast.spring.demo.UserServiceImpl.saveUser(java.lang.String,java.lang.String))

    • 表示返回类型任意,cn.itcast.spring.demo包中的UserServiceImpl类,类中的saveUser方法,参数2个,都是String类型


    execution(* cn.cdut.spring.demo.UserServiceImpl.saveUser(java.lang.String,java.lang.Integer))

    • 表示返回类型任意,cn.cdut.spring.demo包中的UserServiceImpl类,类中的saveUser方法,参数2个,参数1是String类型,参数二是Integer


    execution(* cn.cdut.spring.demo.UserServiceImpl.saveUser(java.lang.String,*))

    • 表示返回类型任意,cn.cdut.spring.demo包中的UserServiceImpl类,类中的saveUser方法,参数2个,参数1是String类型,参数二是任意类型


    execution(* cn.cdut.spring.demo.UserServiceImpl.saveUser(*))

    • 表示返回类型任意,cn.cdut.spring.demo包中的UserServiceImpl类,类中的saveUser方法,参数1个,参数是任意类型


    execution(* cn.cdut.spring.demo.UserServiceImpl.saveUser())

    • 表示返回类型任意,cn.cdut.spring.demo包中的UserServiceImpl类,类中的saveUser方法,没有参数


    execution(* cn.cdut.spring.demo.UserServiceImpl.saveUser(..))

    • 表示返回类型任意,cn.cdut.spring.demo包中的UserServiceImpl类,类中的saveUser方法,参数任意(可以是0个,也可以多个)

    5:throws-pattern?(非必填项):方法上抛出的异常

    项目开发中表达式(最多用)

    1:execution(* cn.cdut.procject.service..*.*(..))
    * 返回类型任意,cn.itcast.procject.service包及其子包中所有类,类中所有方法,参数任意
    2:execution(* *..*.*(..))
    * 返回类型任意,任意包中及其子包中所有类,类中所有方法,参数任意
    3:execution(* *(..))
    * 返回类型任意,任意包中及其子包中所有类,类中所有方法,参数任意

    下面给出一些通用切入点表达式的例子

    任意公共方法的执行:


    execution(public * *(..))

    任何一个名字以“set”开始的方法的执行:


    execution(* set*(..))

    AccountService接口定义的任意方法的执行:


    execution(* com.xyz.service.AccountService.*(..))

    在service包中定义的任意方法的执行:


    execution(* com.xyz.service.*.*(..))

    在service包或其子包中定义的任意方法的执行:


    execution(* com.xyz.service..*.*(..))

    切入点表达式的语法整理如下:

    execution(<访问修饰符>?<返回类型>空格<方法名>(<参数>)<异常>?)
    例如:
    execution(* cn.cdut.spring.a_jdkproxy.CustomerServiceImpl.*(..))
    增强bean对象所有方法
    execution(* cn.cdut.spring..*.*(..))
    增强spring包和子包所有bean所有方法
    提示:最灵活的
    bean(bean Id/bean name)
    例如
    bean(customerService)
    增强spring容器中定义id属性/name属性为customerService的bean中所有方法 bean(*Service)
    :pring容器中的bean,对应bean中的id属性,*Service表示找到所有以Service结尾的id的名称
    within(包.类)
    例如:
    within(cn.cdut.spring..*)
    增强spring包和子包所有bean“所有方法 ”
    this(完整类型)/target(完整类型)
    范围最小,只针对某个类型。
    this对某一个类-(对代理对象有效),target对代理对象无效(只对目标对象有效)
    例如:


    this(cn.cdut.spring.demo.CustomerServiceImpl)

    增强类型所有方法(对代理对象有效)
    增强类型所有方法(对目标对象有效)
    注意:我们一般都对目标对象进行拦截,很少对代理对象进行拦截

    【AspectJ类型匹配的通配符】
    *:匹配任何数量字符(一个);
    ..:匹配任何数量字符的重复(多个),如在类型模式中匹配任何数量子包;而在方法参数模式中匹配任何数量参数。

    展开全文
  • Java正则表达式语法

    千次阅读 2014-03-13 23:53:05
    Java正则表达式 表达式意义: 1.字符 x 字符 x。例如a表示字符a \\ 反斜线字符。在书写时要写为\\\\。(注意:因为java在第一次解析时,把\\\\解析成正则表达式\\,在第二次解析时再解析为\,所以凡是不是1.1列举到...
  • Java lambda表达式

    2019-05-04 20:34:48
    Lambda 表达式,也可称为闭包,它是推动 Java 8 发布的最重要新特性。Lambda 允许把函数作为一个方法的参数(函数作为参数传递进方法中)。使用 Lambda 表达式可以使代码变的更加简洁紧凑。 Lambda标准格式 ...
  • spring切点表达式写法

    2010-12-12 11:50:50
    自从使用AspectJ风格切面配置,使得Spring的切面配置大大简化,但是AspectJ是另外一个开源项目,其规则表达式的语法也稍稍有些怪异。 下面给出一些常见示例的写法: 比如,下面是一个对Service包上所有方法的切面...
  • Lambda表达式省略写法

    2019-11-04 10:18:40
    本文介绍了java选中 Lambda表达式写法的基本规则,介绍了lambda的基本写法
  • AOP切入点表达式写法

    千次阅读 2014-07-03 10:46:08
    执行表达式的格式如下: execution(modifiers-pattern? ret-type-pattern declaring-type-pattern? name-pattern(param-pattern) throws-pattern?) 除了返回类型模式(上面代码片断中的ret-ty
  • Java正则表达式总结

    2013-01-29 13:50:01
    用Google搜索“Java正则表达式”,并不能轻易地找出特别好的关于java正则表达式的总结的文章,我看了几个,转载总结下吧: Java正则表达式的解释说明 : ...
  • Java 正则表达式

    2014-04-14 20:30:37
    Java 正则表达式 表达式意义: 1.字符 x 字符 x。例如a表示字符a \\ 反斜线字符。在书写时要写为\\\\。(注意:因为java在第一次解析时,把\\\\解析成正则表达式\\,在第二次解析时再解析为\,所以凡是不是1.1...
  • 新手小白学JAVA Lambda表达式

    多人点赞 2021-09-18 13:51:02
    函数式编程思想强调:尽量忽略面向对象的复杂语法,强调做什么,而不是通过什么去做 package cn.tedu.lambda; /*本类用于lambda表达式入门 * 需求:在多线程场景下,在控制台输出:多线程程序启动啦*/ public class...
  • Java正则表达式

    千次阅读 2013-06-27 14:40:39
    非捕获型括号的价值体现在几个方面,能使复杂表达式更清晰,不会使维护的人对$1..$2产生 混乱,非捕获型括号是不能捕获的只能用于分组,例如下面的语句一共有3组,但是能够使用$x进行捕获 的只有两组,如果写$3会报错(?:...
  • 正则表达式
  • Java正则表达式 总结

    千次阅读 2013-11-09 10:52:23
    要想全面地掌握怎样构建正则表达式,可以去看JDK文档的java.util.regex的Pattern类的文档。 字符 B 字符B /xhh 16进制值0xhh所表示的字符 /uhhhh 16进制值0xhhhh所表示的Unicode字符 /t Tab /n 换行符...
  • (1). int i = 5; i += i -= i * 3; 刚看到这道题的时候,虽然算对了,但是思路不太正确。 上面的写法可以等价下面这种形式(算是取巧emmm) i = i + (i - (i * 3));...这道题比上面那道复杂一...
  • JAVA正则表达式语法

    千次阅读 2013-11-08 10:20:37
    Java 正则表达式 表达式意义: 1.字符 x 字符 x。例如a表示字符a \\ 反斜线字符。在书写时要写为\\\\。(注意:因为java在第一次解析时,把\\\\解析成正则表达式\\,在第二次解析时再解析为\,所以凡是不是1.1...
  • java正则表达式入门文档引言 正则表达式(regular expression)描述了一种字符串匹配的模式,可以用来:(1)检查一个串中是否含有符合某个规则的子串,并且可以得到这个子串;(2)根据匹配规则对字符串进行灵活的...
  • Java 正则表达式-语法与示例
  • 好处:可以简化对字符串的复杂操作。 弊端:符号定义越多,正则越长,阅读性越差。正则表达式特殊字符的含义: 正则表达式的方法package day25;/* * 具体操作功能: * * 1,匹配:String类
  • java正则表达式文档

    2009-10-11 11:41:00
    正则表达式(regular expression)描述了一种字符串匹配的模式,可以用来:(1)检查一个串...之所以很多人感觉正则表达式比较复杂,一方面是因为大多数的文档没有做到由浅入深地讲解,概念上没有注意先后顺序,给读者
  • Java 正则表达式全攻略 (一)  特此声明 本文并非全部原创,我只是在前人的基础上进行针对Java的补充和完成。特此向各位前辈致敬。本文来源于以下内容: · 维基百科-正则表达式 · 深入浅出之正则...
  • java正则表达式入门文档 引言 正则表达式(regular expression)描述了一种字符串匹配的模式,可以用来:(1)检查一个串中是否含有符合某个规则的子串,并且可以得到这个子串;(2)根据匹配规则对字符串进行灵活...
  • Java 正则表达式全攻略 (一)  特此声明 本文并非全部原创,我只是在前人的基础上进行针对Java的补充和完成。特此向各位前辈致敬。本文来源于以下内容: · 维基百科-正则表达式 · 深入浅出之正则表达式 · ...
  • 从学java开始就没弄清楚过捕获组的用法,一般没有处理复杂字符串的时候也不会去用。之前一直理解错了捕获组的用法,一直以为捕获组是可以循环捕获的 我以为的写法是这样的 (组1(组2))* 即组1循环匹配字符串,其实...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 29,256
精华内容 11,702
关键字:

java复杂表达式写法

java 订阅