精华内容
下载资源
问答
  • Lambda表达式详解

    2020-11-16 18:02:15
    Lambda表达式详解Lambda表达式简介对接口的要求@FunctionalInterfaceLambda基础语法Lambda语法简化Lambda表达式常用示例Lambda表达式引用方法构造方法的引用Lambda表达式创建线程遍历集合删除集合中的某个元素集合内...

    Lambda表达式简介

    Lambda 表达式是 JDK8 的一个新特性,可以取代大部分的匿名内部类,写出更优雅的 Java 代码,尤其在集合的遍历和其他集合操作中,可以极大地优化代码结构。

    JDK 也提供了大量的内置函数式接口供我们使用,使得 Lambda 表达式的运用更加方便、高效。

    对接口的要求

    虽然使用 Lambda 表达式可以对某些接口进行简单的实现,但并不是所有的接口都可以使用 Lambda 表达式来实现。Lambda 规定接口中只能有一个需要被实现的方法,不是规定接口中只能有一个方法

    jdk 8 中有另一个新特性:default, 被 default 修饰的方法会有默认实现,不是必须被实现的方法,所以不影响 Lambda 表达式的使用。

    @FunctionalInterface

    修饰函数式接口的,要求接口中的抽象方法只有一个。 这个注解往往会和 lambda 表达式一起出现。

    Lambda基础语法

    我们这里给出六个接口,后文的全部操作都利用这六个接口来进行阐述。

    /**多参数无返回*/
    @FunctionalInterface
    public interface NoReturnMultiParam {
        void method(int a, int b);
    }
    
    /**无参无返回值*/
    @FunctionalInterface
    public interface NoReturnNoParam {
        void method();
    }
    
    /**一个参数无返回*/
    @FunctionalInterface
    public interface NoReturnOneParam {
        void method(int a);
    }
    
    /**多个参数有返回值*/
    @FunctionalInterface
    public interface ReturnMultiParam {
        int method(int a, int b);
    }
    
    /*** 无参有返回*/
    @FunctionalInterface
    public interface ReturnNoParam {
        int method();
    }
    
    /**一个参数有返回值*/
    @FunctionalInterface
    public interface ReturnOneParam {
        int method(int a);
    }
    

    语法形式为 () -> {},其中 () 用来描述参数列表,{} 用来描述方法体,-> 为 lambda运算符 ,读作(goes to)。

    package com.lambda;
    
    public class Test1 {
    	public static void main(String[] args) {
    		
    		
    		// 无参无返回值
    		NoReturnNoParam noReturnNoParam = ()->{
    			System.out.println("无参数无返回值");
    		};
    		noReturnNoParam.method();
    		
    		
    		//一个参数无返回
            NoReturnOneParam noReturnOneParam = (int a) -> {
                System.out.println("一个参数无返回:" + a);//一个参数无返回:6
            };
            noReturnOneParam.method(6); 
            
            
            //多个参数无返回
            NoReturnMultiParam noReturnMultiParam = (int a, int b) -> {
                System.out.println("多个参数无返回值:" + "{" + a +"," + + b +"}");//多个参数无返回值:{6,8}
            };
            noReturnMultiParam.method(6, 8);
            
            
            //无参有返回值
            ReturnNoParam returnNoParam = () -> {
                return 1;
            };
            int res = returnNoParam.method();
            System.out.println("无参有返回值return:" + res); //无参有返回值return:1
            
            
            //一个参数有返回值
            ReturnOneParam returnOneParam = (int a) -> {
                System.out.println("一个参数有返回值:" + a); //一个参数有返回值:6
                return 2;
            };
            int res2 = returnOneParam.method(6);
            System.out.println("return:" + res2); //return:2
            
            
            //多个参数有返回值
            ReturnMultiParam returnMultiParam = (int a, int b) -> {
                System.out.println("多个参数有返回值:" + "{" + a + "," + b +"}");// 多个参数有返回值:{6,8}
                return a+b;
            };
            int res3 = returnMultiParam.method(6, 8);
            System.out.println("return:" + res3); //return:14
    	}
    }
    

    Lambda语法简化

    我们可以通过观察以下代码来完成代码的进一步简化,写出更加优雅的代码。

    package com.lambda;
    
    public class Test2 {
    	public static void main(String[] args) {
    
            //1.简化参数类型,可以不写参数类型,但是必须所有参数都不写
            NoReturnMultiParam lamdba1 = (a, b) -> {
                System.out.println("简化参数类型");
            };
            lamdba1.method(1, 2);
    
            //2.简化参数小括号,如果只有一个参数则可以省略参数小括号
            NoReturnOneParam lambda2 = a -> {
                System.out.println("简化参数小括号");
            };
            lambda2.method(1);
    
            //3.简化方法体大括号,如果方法条只有一条语句,则可以胜率方法体大括号
            NoReturnNoParam lambda3 = () -> System.out.println("简化方法体大括号");
            lambda3.method();
    
            //4.如果方法体只有一条语句,并且是 return 语句,则可以省略方法体大括号
            ReturnOneParam lambda4 = a -> a+3;
            System.out.println(lambda4.method(5)); // 8
    
            ReturnMultiParam lambda5 = (a, b) -> a+b;
            System.out.println(lambda5.method(1, 1)); // 2
        }
    }
    

    Lambda表达式常用示例

    Lambda表达式引用方法

    有时候我们不是必须要自己重写某个匿名内部类的方法,我们可以利用 lambda表达式的接口快速指向一个已经被实现的方法
    语法: 方法归属者::方法名。静态方法归属者为类名,普通方法归属者为对象。

    package com.lambda;
    
    public class Exe1 {
    	
        /**
         * 要求
         * 1.参数数量和类型要与接口中定义的一致
         * 2.返回值类型要与接口中定义的一致
         */
        public static int doubleNum(int a) {
            return a * 2;
        }
    
        public int addTwo(int a) {
            return a + 2;
        }
        
        
        
    	public static void main(String[] args) {
    		
            ReturnOneParam lambda1 = a -> doubleNum(a);
            System.out.println(lambda1.method(3));// 6
            
            //lambda2 引用了已经实现的 doubleNum 静态方法,等价于上面的写法
            ReturnOneParam lambda2 = Exe1::doubleNum;
            System.out.println(lambda2.method(3)); // 6
            
            Exe1 exe = new Exe1();
            //lambda3 引用了已经实现的 addTwo 普通方法
            ReturnOneParam lambda3 = exe::addTwo;
            System.out.println(lambda3.method(2)); // 4
    	}
    }
    

    构造方法的引用

    一般我们需要声明接口,该接口作为对象的生成器,通过 类名::new 的方式来实例化对象,然后调用方法返回对象。

    interface ItemCreatorBlankConstruct {
        Item getItem();
    }
    interface ItemCreatorParamContruct {
        Item getItem(int id, String name, double price);
    }
    
    public class Exe2 {
        public static void main(String[] args) {
            ItemCreatorBlankConstruct creator = () -> new Item();
            Item item = creator.getItem();
    		// 等同于上面的写法
            ItemCreatorBlankConstruct creator2 = Item::new;
            Item item2 = creator2.getItem();
    
            ItemCreatorParamContruct creator3 = Item::new;
            Item item3 = creator3.getItem(112, "鼠标", 135.99);
        }
    }
    

    Lambda表达式创建线程

    我们以往都是通过创建 Thread 对象,然后通过匿名内部类重写 run() 方法,一提到匿名内部类我们就应该想到可以使用 lambda 表达式来简化线程的创建过程。

    Thread t = new Thread( () -> {
    	for (int i = 0; i < 10; i++) {
            System.out.println(2 + ":" + i);
        }
    });
    t.start();
    

    遍历集合

    我们可以调用集合的 public void forEach(Consumer<? super E> action) 方法,通过 lambda 表达式的方式遍历集合中的元素。以下是 Consumer 接口的方法以及遍历集合的操作。Consumer 接口是 jdk 为我们提供的一个函数式接口。

    @FunctionalInterface
    public interface Consumer<T> {
    
        /**
         * Performs this operation on the given argument.
         *
         * @param t the input argument
         */
        void accept(T t);
    
        /**
         * Returns a composed {@code Consumer} that performs, in sequence, this
         * operation followed by the {@code after} operation. If performing either
         * operation throws an exception, it is relayed to the caller of the
         * composed operation.  If performing this operation throws an exception,
         * the {@code after} operation will not be performed.
         *
         * @param after the operation to perform after this operation
         * @return a composed {@code Consumer} that performs in sequence this
         * operation followed by the {@code after} operation
         * @throws NullPointerException if {@code after} is null
         */
        default Consumer<T> andThen(Consumer<? super T> after) {
            Objects.requireNonNull(after);
            return (T t) -> { accept(t); after.accept(t); };
        }
    }
    
    import java.util.ArrayList;
    import java.util.Collections;
    import java.util.List;
    
    public class Exe2 {
    	public static void main(String[] args) {
    	      List<Integer> list = new ArrayList<>();
    
    	      Collections.addAll(list, 1,2,3,4,5);
    
    	      //lambda表达式 方法引用
    	      list.forEach(System.out::print); //1 2 3 4 5 
    
    	      list.forEach(element -> {
    	        if (element % 2 == 0) {
    	          System.out.println(element);// 2 4
    	        }
    	      });
    	}
    }
    

    删除集合中的某个元素

    我们通过 public boolean removeIf(Predicate<? super E> filter) 方法来删除集合中的某个元素,Predicate 也是 jdk 为我们提供的一个函数式接口,可以简化程序的编写。

          ArrayList<Item> items = new ArrayList<>();
          items.add(new Item(11, "小牙刷", 12.05 ));
          items.add(new Item(5, "日本马桶盖", 999.05 ));
          items.add(new Item(7, "格力空调", 888.88 ));
          items.add(new Item(17, "肥皂", 2.00 ));
          items.add(new Item(9, "冰箱", 4200.00 ));
    
          items.removeIf(ele -> ele.getId() == 7);
    
          //通过 foreach 遍历,查看是否已经删除
          items.forEach(System.out::println);
    

    集合内元素排序

    在以前我们若要为集合内的元素排序,就必须调用 sort 方法,传入比较器匿名内部类重写 compare 方法,我们现在可以使用 lambda 表达式来简化代码。

    ArrayList<Item> list = new ArrayList<>();
            list.add(new Item(13, "背心", 7.80));
            list.add(new Item(11, "半袖", 37.80));
            list.add(new Item(14, "风衣", 139.80));
            list.add(new Item(12, "秋裤", 55.33));
    
            /*
            list.sort(new Comparator<Item>() {
                @Override
                public int compare(Item o1, Item o2) {
                    return o1.getId()  - o2.getId();
                }
            });
            */
    
            list.sort((o1, o2) -> o1.getId() - o2.getId());
    
            System.out.println(list);
    
    展开全文
  • Lambda表达式可以取代大部分匿名内部类,可以优化代码结构。 可以取代匿名内部类?什么意思呢? 在以前如果我们需要对集合排序,我们是这样做: Integer[] arr= {3,2,1}; Arrays.sort(arr, new Comparator<...

    Lambda表达式

    简介

    Lambda表达式可以取代大部分匿名内部类,可以优化代码结构。

    可以取代匿名内部类?什么意思呢?

    在以前如果我们需要对集合排序,我们是这样做:

    Integer[] arr= {3,2,1};
    Arrays.sort(arr, new Comparator<Integer>() {
    
    	@Override
    	public int compare(Integer o1, Integer o2) {
    		return o1-o2;
    	}
    });
    System.out.println(Arrays.toString(arr));
    

    使用Arrays类提供的sort方法传入一个指定排序规则的Comparator,如果我们使用匿名内部类的话,可以看到整个内部类中只用return o1-o2;语句是有用的,其他的都是多余的,为了这一句话我们多写了很多代码。那么,有了Lambda表达式后我们就可以很轻松的解决这个问题了。

    java8中新增了Lambda表达式,现在我们可以这样做:

    Integer[] arr= {3,2,1};
    Arrays.sort(arr, (x,y)->x-y);
    System.out.println(Arrays.toString(arr));
    

    那么Lambda是如何实现的呢?我们知道sort方法需要传入一个Comparator,而Comparator是一个接口,那么我们来看看Comparator接口是怎样定义的:

    @FunctionalInterface
    public interface Comparator<T> {
    

    Comparator能够支持Lambda表达式的秘密就是类上标注的@FunctionalInterface注解,被这个注解标注的接口只能有一个抽象方法,我们知道我们写Lambda表达式时并没有指定方法,那么当使用Lambda表达式时我们重新的就是这个方法。

    Lambda表达式基本语法

    语法形式为 () -> {},其中 () 用来描述参数列表,{} 用来描述方法体,-> 为 lambda运算符

    1. 接口无参无返回

      @FunctionalInterface
      interface NoParamNoReturn {
      	void lambda();
      }
      
      @Test
      public void test() {
        NoParamNoReturn noParamNoReturn=()->{System.out.println("No param No return");};
        noParamNoReturn.lambda();
      }
      //如果方法内只有一个语句那么{}可以省略
      @Test
      public void test() {
        NoParamNoReturn noParamNoReturn=()->System.out.println("No param No return");
        noParamNoReturn.lambda();
      }
      
    2. 接口有一个或多个参数无返回

      @FunctionalInterface
      interface OneParamNoReturn{
      	void lambda(int x);
      }
      @Test
      public void test() {
        OneParamNoReturn oneParamNoReturn=(int x)->System.out.println(x);
        oneParamNoReturn.lambda(10);
      }
      //如果方法只有一个参数那么()可以省略
      //方法参数的类型也可以省略,编译器会根据方法参数类型推断
      @Test
      public void test() {
        OneParamNoReturn oneParamNoReturn=x->System.out.println(x);
        oneParamNoReturn.lambda(10);
      }
      
    3. 接口无参数有返回值

      @FunctionalInterface
      interface NoParamHasReturn{
      	int lambda();
      }
      @Test
      public void test() {
        NoParamHasReturn noParamHasReturn=()->{return 10;};
        noParamHasReturn.lambda();
      }
      //当方法只有return语句时,可以省略{}和return
      @Test
      public void test() {
        NoParamHasReturn noParamHasReturn=()->10;
        noParamHasReturn.lambda();
      }
      
    4. 接口有一个或多个参数有返回值

      @FunctionalInterface
      interface HasParamHasReturn{
      	int lambda(int x,int y);
      }
      @Test
      public void test() {
        HasParamHasReturn hasParamHasReturn=(x,y)->x+y;
        hasParamHasReturn.lambda(10, 20);
      }
      

      Lambda表达式引用方法

      我们可以使用lambda表达式把接口快速指向一个已经实现了的方法

      语法:方法归属者::方法名 静态方法的归属者为类名,普通方法归属者为对象

      @FunctionalInterface
      interface HasParamHasReturn{
      	int lambda(int x,int y);
      }
      public class LambdaTest{
        public int add(int x,int y) {
          return x+y;
        }
      //lambda表达式指向对象方法
        @Test public void test() {
          LambdaTest lt=new LambdaTest();
          HasParamHasReturn hasParamHasReturn=lt::add;
          hasParamHasReturn.lambda(10, 20);
        }
        
        public static int sub(int x,int y) {
          return x-y;
        }
      
        //lambda表达式引用静态方法
        @Test
        public void test12() {
          HasParamHasReturn hasParamHasReturn=LambdaTest::sub;
          hasParamHasReturn.lambda(10, 20);
        } 
      }
      

      lambda表达式引用构造函数创建对象

      语法:类名::new;

      class User{
      	String name;
      	int age;
      	
      	public User() {}
      	
      	public User(String name, int age) {
      		super();
      		this.name = name;
      		this.age = age;
      	}
      	
      }
      
      @FunctionalInterface
      interface UserCreatorBlankConstruct{
      	User getUser();
      }
      
      //使用lambda表达式引用构造器
      @Test
      public void test13() {
        UserCreatorBlankConstruct creator1=User::new;
        creator1.getUser();
      }
      
      @FunctionalInterface
      interface UserCreatorParamConstruct{
      	User getUser(String name,int age);
      }
      
      @Test
      public void test13() {
        UserCreatorParamConstruct creator2=User::new;
        creator2.getUser("tom", 20);
      }
      

      java8为我们提供了4个核心的函数式接口

      1. 消费型接口
    @FunctionalInterface
    public interface Consumer<T> {
    void accept(T t);
    }
    
    1. 供给型接口

      @FunctionalInterface
      public interface Supplier<T> {
          T get();
      }
      
    2. 函数型接口

      @FunctionalInterface
      public interface Function<T, R> {
          R apply(T t);
      }
      
    3. 断言型接口

      @FunctionalInterface
      public interface Predicate<T> {
          boolean test(T t);
      }
      

      怎么用呢?

      遍历数组

      @Test
      	public void test() {
      		List<Integer> list=new ArrayList<>();
      		list.add(1);
      		list.add(3);
      		list.add(5);
      		list.add(7);
      		list.forEach(System.out::println);
      	}
      

      创建对象

      @Test
      public void test() {
        Supplier<User> supplier=User::new;
        User user = supplier.get();
      }
      

      去除前后空格并转为大写

      @Test
      public void test16() {
        Function<String, String> fun=s->{s=s.trim();s=s.toUpperCase();return s;};
        String apply = fun.apply(" abCd");
      }
      

      删除集合元素

      @Test
      public void test() {
        List<User> list=new ArrayList<>();
        list.add(new User("tom",20));
        list.add(new User("jack",18));
        list.add(new User("marry",22));
      
        list.removeIf(e->e.getName()=="jack");
      }
      

    那如果我们要用内置函数式接口创建对象,怎么做呢?

    @Test
    public void test() {
      Supplier<User> supplier=User::new;
      User user = supplier.get();
      System.out.println(user);//User [name=null, age=0]
    }
    

    那到底使用的是哪个构造器呢?通过输出创建的对象可以发现调用的是无参构造器,即调用构造器参数个数对应Supplier中get方法的参数个数的构造器

    那么问题又来了,如果我们要使用两个参数的构造器,那Supplier也不行啊,Function的apply方法也只有一个参数,怎么办?那我们去java.util.function包下找找有没有可以用的接口

    @FunctionalInterface
    public interface BiFunction<T, U, R> {
        R apply(T t, U u);
    }
    //使用内置函数式接口创建对象
    @Test
    public void test20() {
      BiFunction<String,Integer,User> biFunction=User::new;
      User user = biFunction.apply("tom", 20);
      System.out.println(user);//User [name=tom, age=20]
    }
    

    四个基本接口参数个数不够用也可以类似的去java.util.function包下找找有没有申明好的函数式接口

    最后一个问题,我发现

    list.forEach(System.out::println);
    

    遍历List时,使用的forEach的参数Consumer的accept方法是这么写的,我第一个想到的是,out是System的一个内部类,但是当我点进去,发现是这样的

    public final static PrintStream out = null;
    

    out是一个静态的成员变量,那我的理解就是System.out其实是一个对象

    这样System.out::println的写法其实也就是 对象名::方法名

    我是这样理解的,如果错了还请赐教!

    展开全文
  • java-Lambda表达式详解

    2020-08-25 19:25:45
    java-Lambda表达式详解前言一、了解Lambda1.Lambda是什么,为什么要使用它?2.Lambda使用的条件。3.@FunctionalInterface4.基本语法二、使用案例1.用Lambda优化自定义字符串排序2.运行结果3. Lambda小技巧总结欢迎...


    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


    前言

    Lambda 表达式(lambda expression)是一个匿名函数,Lambda表达式基于数学中的λ演算得名,直接对应于其中的lambda抽象(lambda abstraction),是一个匿名函数,即没有函数名的函数。


    以下是本篇文章正文内容。

    一、了解Lambda

    1.Lambda是什么,为什么要使用它?

    Lambda是jdk8的新特性,它可以代替大部分匿名内部类,从而优化我们的代码,提高代码的可读性。(注意:仅jdk8及之后的版本有效)

    2.Lambda使用的条件。

    不是所有的接口都能使用Lambda,只有接口中有且仅有一个需要必须被实现的方法时,才能使用Lambda,当然这个接口可以有其他方法,比如用default修饰的方法,或者是静态的方法.(default:该方法不是必须实现,它有默认实现,也就是接口中有方法体“有点类似于子类与父类的覆盖-override”)

    3.@FunctionalInterface

    @FunctionalInterface是修饰函数式接口的,要求接口中的抽象方法只有一个。 这个注解往往会和 lambda 表达式一起出现。

    4.基本语法

    Lambda表达式:() -> {}
    ():参数列表
    ->: 为 lambda运算符 ,读作(goes to)
    {}:方法体

    二、使用案例

    1.用Lambda优化自定义字符串排序

    代码如下(示例):

    class Demo1 {
        public static void main(String[] args){
            String[] arrr=new String[]{"111","22","3"};
            Arrays.sort(arrr, new Comparator<String>() {
                @Override
                public int compare(String a, String b) {
                    return a.length()-b.length();
                }
            });
            System.out.println(Arrays.toString(arrr));
    
        }
    
    使用Lambda优化后:
    public class Demo1 {
        public static void main(String[] args){
            String[] arrr=new String[]{"111","22","3"};
            Arrays.sort(arrr,(a,b)->a.length()-b.length());
            System.out.println(Arrays.toString(arrr));
    
        }
    
    }
    

    2.运行结果

    在这里插入图片描述

    3. Lambda小技巧

    1.小括号内可以不写参数类型,不写就全不写,写了就要全写
    例:

    (String a,String b)->{
    int num=a.length()-b.length();
    return num;
    }
    
    (a,b)->{
    int num=a.length()-b.length();
    return num;
    }
    

    2.当只有一个参数时可以省略小括号

     a->{
    int num=a.length();
    return num;
    }
    

    3.当只有一条语句且该语句为return时可以省略{}

    (a,b)->a.length()-b.length();
    

    总结

    以上就是今天要讲的内容,本文仅仅简单介绍了Lambda的使用。

    展开全文
  • 写一个类似于通讯录的简单功能,要求是首先按照部门显示列表,然后点击部门下拉显示部门里面的人员信息,且人员信息按照职位排序。 先分析数据结构: 最外层是部门,部门里面是员工,且项目是统一返回数据格式。 ...

    最近遇到个需求是这样的:

    写一个类似于通讯录的简单功能,要求是首先按照部门显示列表,然后点击部门下拉显示部门里面的人员信息,且人员信息按照职位排序。

    先分析数据结构:

    最外层是部门,部门里面是员工,且项目是统一返回数据格式。

    {
        "code": 0,
        "data": [
            {
                "name": "部门名称",
                "userData": [
                    {
                        "deptName": "部门名称",
                        "info": "部门名称+职位",
                        "phone": "电话号码",
                        "userName": "员工姓名"
                    }
                ]
            },
            {
                "name": "部门名称",
                "userData": [
                    {
                        "deptName": "部门名称",
                        "info": "部门名称+职位",
                        "phone": "电话号码",
                        "userName": "员工姓名"
                    }
                ]
            }
        ],
        "message": "success"
    }

    数据格式大概就是这样。然后分析写法。正常来说需要用sql将这些数据一次性分组并返回出来,本人没有找到合适的方法。然后打算用最原始的方法,就是先查出所有的部门,再遍历部门查询出部门里面所有的人员,再将数据返回。下面贴上代码。

    List<PageData> deptAll = (List<PageData>) dao.findForList("AddressListMapper.querydeptAll", pageData);
            //创建list保存所有部门和部门人员
            List<PageData> deptPersonnelAll = new ArrayList<PageData>();
            //遍历获取到的部门查询相对应得人员信息
    /*        for (HashMap<String, Object> dept : deptAll) {
                //获取部门名称
                String deptName = String.valueOf(dept.get("name"));
                //获取部门code
                String deptCode = String.valueOf(dept.get("code"));
                //根据部门code查询部门对应的人员
                PageData pageDatap = new PageData();
                pageDatap.put("deptid", deptCode);
                ArrayList<PageData> personnelList = queryPersonnel(pageDatap);
                //将数据存封装为map并存进list
                PageData deptSingle = new PageData();
                deptSingle.put("name", deptName);
                deptSingle.put("userData", personnelList);
                deptPersonnelAll.add(deptSingle);
            }*/
            deptAll.stream().forEach(dept -> {
                //获取部门名称
                String deptName = String.valueOf(dept.get("name"));
                //获取部门code
                String deptCode = String.valueOf(dept.get("code"));
                //根据部门code查询部门对应的人员
                PageData pageDatap = new PageData();
                pageDatap.put("deptid", deptCode);
                ArrayList<PageData> personnelList = null;
                try {
                    personnelList = queryPersonnel(pageDatap);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                //将数据存封装为map并存进list
                PageData deptSingle = new PageData();
                deptSingle.put("name", deptName);
                deptSingle.put("userData", personnelList);
                deptPersonnelAll.add(deptSingle);
            });
            return deptPersonnelAll;

    上面遍历集合写了两种方式,一种是以前的for循环写法,另一种是用表达式。

    但是这种方式会出现一个性能问题,比如说有10000个部门,就需要查询10000次数据库。这样会增大数据库的压力和查询时间。所以这样就需要优化。

    优化:

    优化的方式就是在数据一次查出所有的人员信息,并将人员信息和部门信息进行关联,这样就能知道每个人所对应的部门。然后用java代码可以对数据进行分组。

    贴代码:

    public List<Map<String, Object>> getAllPersonnel(PageData pageData) throws Exception {
        //查询类型对应的人员
        List<AddressList> addressList = (List<AddressList>) dao.findForList("AddressListMapper.getAllPersonnel", pageData);
        //lambda表达式对数据进行分组
        Map<String, List<AddressList>> collect = addressList.stream().collect(Collectors.groupingBy(AddressList::getDeptName));
        //处理分组后的数据
        //创建一个list集合存储所有数据
        List<Map<String, Object>> maps = new ArrayList<>();
        //遍历分组后的数据,进行组装
        collect.forEach((k, v) -> {
            HashMap<String, Object> map = new HashMap<>();
            map.put("name", k);
            map.put("userData", v);
            maps.add(map);
        });
        return maps;
    }

    这边分组是用的表达式分组的,定义一个对象,将数据库查出来的数据封装进去,然后按照属性进行分组。这样就可以避免多次请求数据库。

    处理排序:

    这样优化完后还有一个排序的问题。

    解决办法:

    上面代码中groupingBy有三个参数

    第一个参数:分组按照什么分类

    第二个参数:分组最后用什么容器保存返回值(默认是HashMap::new)

    第三个参数:按照第一个参数分类后,对应的分类的结果如何收集。(Collectors.toList)

    这边主要问题是数据库里面将数据排序好之后返回到代码里面。代码里面对数据进行分组之后,数据的顺序发生了改变。

    map里面的有序集合LinkedHashMap。这里可以使用这个集合作为分组后用来保存返回值的容器。这样就解决了分组后的排序问题。

     

    展开全文
  • Lambda 表达式是 JDK8 的一个新特性,可以取代大部分的匿名内部类,写出更优雅的 Java 代码,尤其在集合的遍历和其他集合操作中,可以极大地优化代码结构。 λ希腊字母表中排序第十一位的字母,英语名称为Lambda 其...
  • Lambda表达式】让你的代码逼范十足~~

    千次阅读 多人点赞 2020-06-10 16:10:50
    Lambda表达式是 JDK8的新特性,可以取代大部分的匿名内部类,写出更优雅简洁的Java代码,我在日常撸代码的时候常用的地方是集合的遍历和其他集合操作中,极大的优化了代码结构,总之一句话就是少写代码,可以提高...
  • 最近遇到个需求是这样的:写一个类似于通讯录的简单功能,要求是首先按照部门显示列表,然后点击部门下拉显示部门里面的人员信息,且人员信息按照职位排序。先分析数据结构:最外层是部门,部门里面是员工,且项目是...
  • Lambda 表达式Lambda允许把函数作为一个方法的参数(函数)作为参数传递进方法中。 该表达式的目的是:优化我们的代码,使我们的代码更加的简洁。 举例说明: //使用java7排序 private void sortUsingJava7...
  • 排序接口优化 先来体验一下lambda最直观的优点:简洁代码  //匿名内部类  Comparator&lt;Integer&gt; cpt = new Comparator&lt;Integer&gt;() {  @Override  public int compare(Integer o...
  • 文章目录第十四章 流式编程流支持流创建随机数流int 类型的范围generate()iterate()流的建造者模式Arrays正则表达式中间操作跟踪和调试流元素排序移除元素应用函数到元素在 `map()` 中组合流Optional类便利函数创建 ...
  • lambda表达式 lambda的优化 JDK8中可以使用以下简略写法 new Thread(() -> System.out.println("多线程任务执行!")).start(); // 启动线程 Arrays.sort(array,(a,b)->a.getAge()-b.getAge()) //排序 Lambda...
  • lambda表达式lambda的优化JDK8中可以使用以下简略写法new Thread(() -> System.out.println("多线程任务执行!")).start(); // 启动线程Arrays.sort(array,(a,b)->a.getAge()-b.getAge()) //排序Lambda的格式...
  • Java8的新特性主要是Lambda表达式和流,当流和Lambda表达式结合起来一起使用时,因为流申明式处理数据集合的特点,可以让代码变得简洁易读放大招,流如何简化代码如果有一个需求,需要对数据库查询到的菜肴进行一个...
  • 通过使用Java 8的Lambda表达式,实现冒泡排序代码如下: void bubbleSort(Integer[] arr) { int n = arr.length; IntStream.range(0, n - 1) .flatMap(i -&gt; IntStream.range(i + 1, n - i)) .forEach(j -...
  • Java 8 Lambda使用

    2020-10-20 11:43:07
    Java 8 Lambda使用Lambda介绍本质函数式接口函数式接口定义stream流的Intermediate方法(中间操作)流的Terminal方法(终结操作)filtermapsorted自然排序自定义排序...Lambda表达式本质是函数式接口的实例 函数式接口 函
  • Java8的新特性主要是Lambda表达式和流,当流和Lambda表达式结合起来一起使用时,因为流申明式处理数据集合的特点,可以让代码变得简洁易读 放大招,流如何简化代码 如果有一个需求,需要对数据库查询到的菜肴进行...
  • Java8的新特性主要是Lambda表达式和流,当流和Lambda表达式结合起来一起使用时,因为流申明式处理数据集合的特点,可以让代码变得简洁易读 一、流如何简化代码 如果有一个需求,需要对数据库查询到的菜肴进行一个...
  • Stream API优化代码

    2019-10-09 20:34:53
    Java8的新特性主要是Lambda表达式和流,当流和Lambda表达式结合起来一起使用时,因为流申明式处理数据集合的特点,可以让代码变得简洁易读 放大招,流如何简化代码 如果有一个需求,需要对数据库查询到的用户进行...
  • Lambda表达式是JDK8的一个新特性,可以取代大部分的匿名内部类,写出更优雅的Java代码,尤其在集合的遍历和其他集合操作中,可以极大 地优化代码结构。 JDK也提供了大量的内置函数式接口供我们使用,使得Lambda...
  • 腾讯 IEG Unity 面经

    千次阅读 2018-11-01 09:17:09
    问题有点多。我会分块列举 基础相关 1.Animator的使用和机制 以及与Animation的区别 2.什么是弱引用?弱引用的使用和作用?弱引用和强引用的区别?...了解过动画压缩吗,3D...6.C# lambda表达式和表达式树的用法? ...
  • 流的一个核心好处是:它使得程序更加短小并且易于理解,当结合 Lambda 表达式和方法引用时,会让人感觉自成一体。总而言之,流就是一种高效且易于使用的处理数据的方式。 观察下面的例子: public class Randoms { ...
  •  ◆ 回顾.NET体系结构、对象、泛型、继承、数组、运算符、类型强制转换、委托、事件、Lambda表达式等  ◆ 详细论述C#中的动态对象、命名参数和可选参数、COM专用的交互操作功能、安全类型变体  ◆ 阐述.NET 4的...
  • 8.2.3lambda表达式外部的变量 8.3 事件 8.3.1 事件发布程序 8.3.2 事件侦听器 8.3.3 弱事件 8.4 小结 第9章 字符串和正则表达式 9.1 system .string类 9.1.1 创建字符串 9.1.2string builder成员 9.1.3 格式字符串 ...
  • 第8章委托、lambda表达式和事件189 8.1引用方法189 8.2委托190 8.2.1声明委托190 8.2.2使用委托191 8.2.3简单的委托示例194 8.2.4Action<;T>;和Func<;T>;委托196 8.2.5BubbleSorter示例197 8.2.6多播委托199 ...
  • 主要包括网站开发常备技术、前端技术应用开发、操作Office软件(Word/Excel)、ADO.NET数据库操作技术、LINQ技术、XML文件、水晶报表、Web Service服务、网站性能优化与安全策略、程序开发设计模式与架构、网站设计...
  • Python参考手册(第4版 中文高清版)

    热门讨论 2013-03-23 17:20:57
    3.9.3 对象比较与排序 3.9.4 类型检查 3.9.5 属性访问 3.9.6 属性包装与描述符 3.9.7 序列与映射方法 3.9.8 迭代 3.9.9 数学操作 3.9.10 可调用接口 3.9.11 上下文管理协议 3.9.12 对象检查与dir() 第4章 运算符与...
  • 9.12 vb中的lambda表达式 387 9.13 小结 389 第10章 ado.net和linq 391 10.1 ado.net的体系结构 392 10.2 ado.net的基本功能 393 10.2.1 ado.net的常见任务 393 10.2.2 ado.net的基本名称空间和类...

空空如也

空空如也

1 2 3
收藏数 47
精华内容 18
关键字:

lambda表达式排序优化