优化简洁代码(收集记录)

此文章用于记录代码优化相关方法

1.Java Optional(JDK8以上)

下面代码中的List放入了很多Person对象,其中有的对象是null的,如果不加校验调用Person的getXXX()方法肯定会报空指针错误,一般我们采取的方案就是加上if判断:

public class DemoUtils {
 
  public static void main(String[] args) {
    List<Person> personList = new ArrayList<>();
    personList.add(new Person());
    personList.add(null);
    personList.add(new Person("小明",10));
    personList.add(new Person("小红",12));
     
    for (Person person : personList) {
    //if判空逻辑
      if (person != null) {
        System.out.println(person.getName());
        System.out.println(person.getAge());
      }
    }
  }
 
  static class Person {
    private String name;
    private int age;
 
    public Person() {
    }
 
    public Person(String name, int age) {
      this.name = name;
      this.age = age;
    }
 
    public String getName() {
      return name;
    }
    public void setName(String name) {
      this.name = name;
    }
    public int getAge() {
      return age;
    }
    public void setAge(int age) {
      this.age = age;
    }
  }
}

上面方法虽实现目的,但是代码繁多,Java新特性Stream API 与 Optional 提供了更加优雅的方法:

利用Stream API 中的 filter将队列中的空对象过滤掉,filter(Objects::nonNull)的意思是,list中的每个元素执行Objects的nonNull()方法,返回false的元素被过滤掉,保留返回true的元素。

 public static void main(String[] args) {
    List<Person> personList = new ArrayList<>();
    personList.add(new Person());
    personList.add(null);
    personList.add(new Person("小明",10));
    personList.add(new Person("小红",12));

     //剔除之前
        log.info("剔除之前:{}", JSON.toJSONString(personList));
        //剔除null数据
        List<Person> collect = personList.stream().filter(Objects::nonNull).collect(Collectors.toList());
        log.info("剔除之后:{}", JSON.toJSONString(collect));
  }

示例中的personList本身也可能会null,如果业务逻辑中要求personList为null时打日志报警,可以用Optional优雅的实现:

public static void main(String[] args) {
 Person pnull1 = null;
        Person pnull2 = null;
        Person ps = new Person("小明", 10);
        //返回 {"age":10,"name":"小明"}  取is not null 的值 。
        Person person = Optional.ofNullable(ps).orElse(pnull1);
        //返回 null   取is not null 的值 。如果两个都 is null 返回  null
        Person person1 = Optional.ofNullable(pnull1).orElse(pnull2);
        //返回 Optional.empty  获取pnull2的name,如果pnull2 is null 返回 isPresent=false ,且没有值
        Optional<String> listString = Optional.ofNullable(pnull2).map(Person::getName);
        //返回 小明   获取ps的name,如果ps  is not null返回 isPresent=true ,有值
        Optional<String> listString2 = Optional.ofNullable(ps).map(Person::getName);
        //返回 小明  获取ps中的name,如果为空返回一个默认值
        String result = Optional.ofNullable(ps)
                .map(c -> c.getName())
                .orElse("default");
        //返回 default  获取pnull2中的name,如果为空返回一个默认值
        String result2 = Optional.ofNullable(pnull2)
                .map(c -> c.getName())
                .orElse("default");

        log.info("person:{}", JSON.toJSONString(person));
        log.info("person1:{}", JSON.toJSONString(person1));
        log.info("isPresent:{};listString:{}", listString.isPresent(), listString);
        log.info("isPresent:{};listString2:{}", listString2.isPresent(), listString2);
        log.info("result:{}", result);
        log.info("result2:{}", result2);

  //如果有null 直接返回,且return
  Optional.ofNullable(ps).orElseGet(() -> {
    log.error("personList为null!");
    return new ArrayList<>();
  }).stream().filter(Objects::nonNull).forEach(person -> {
//不为空则打印结果
    log.info(person.getName());
    log.info(person.getAge());
  });
}

2.Stream

首先创建一个Person对象作为后面测试使用


class Person {
    private String name;
    private int age;

    public Person() {
    }

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}

可以先看一下Stream的作用:代码看上去简洁有美观

//    import java.util.*;
//     import java.util.stream.Collectors;
    @Test
    void Test01() {
        List<Person> personList = new ArrayList<>();
        personList.add(new Person("小明", 10));
        personList.add(new Person("小皇", 20));
        personList.add(new Person("小菜", 30));
        personList.add(new Person("小红", 40));

        //获取数据
        List<String> personListOut = personList.stream()
                .filter(x -> x.getAge() > 15)  //获取age>0
                .sorted(Comparator.comparing(Person::getAge).reversed())    //根据age排序  reversed倒序
                .map(Person::getName)   //只获取name
                .collect(Collectors.toList());   //转化菜list
        log.info("personListOut:{}", personListOut);
        log.info("personListOut:{}", JSON.toJSONString(personListOut));
    }

下面介绍一些常用的使用:

1创建数组

/**
     * 创建数组
     */
    @Test
    public void TestArrayStream() {
        //1.通过Arrays.stream
        //1.1基本类型
        int[] arr = new int[]{1, 2, 3, 4};
        IntStream intStream = Arrays.stream(arr);
        log.info("intStream:{}", JSON.toJSONString(intStream));
        //1.2引用类型
        Person[] personArray = new Person[]{new Person("a", 10), new Person("b", 20)};
        Stream<Person> personStream = Arrays.stream(personArray);
        personStream.forEach(c -> log.info("personStream:{}", JSON.toJSONString(c)));
        //2.通过Stream.of
        Stream<Integer> stream1 = Stream.of(10, 20, 30, 40);
        stream1.forEach(c -> log.info("stream1:{}", c.toString()));
    }

2大小写转化
 

   /**
     * map把一种类型的流转换为另外一种类型的流 
     */
    @Test
    public void testMap() {
        String[] arr = new String[]{"yes", "YES", "no", "NO"};
        // 把所有大写全部转化为小写
        List<String> collect = Arrays.stream(arr).map(x -> x.toLowerCase()).collect(Collectors.toList());
        log.info("collect:{}", JSON.toJSONString(collect));

        // 把所有小写全部转化为大写
        List<String> collect2 = Arrays.stream(arr).map(x -> x.toUpperCase()).collect(Collectors.toList());
        log.info("collect2:{}", JSON.toJSONString(collect2));
    }

3filter:过滤流, 筛选数据

/**
     * filter:过滤流, 筛选数据
     */
    @Test
    public void testFilter() {
        Integer[] arr = new Integer[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
        List<Integer> collect = Arrays.stream(arr).filter(x -> x > 4 && x < 9).collect(Collectors.toList());
        log.info("collect:{}", collect);
    }

4.fileMap

 /**
     * flapMap:多个list/数组合并为一个
     */
    @Test
    public void testFlapMap() {
        String[] arr1 = {"a", "b", "c", "d"};
        String[] arr2 = {"1", "2", "3", "4"};
        List<String> collect = Stream.of(arr1, arr2).flatMap(Arrays::stream).collect(Collectors.toList());
        List<String> strings = new ArrayList<>();
        strings.add("1");
        strings.add("2");
        List<String> strings2 = new ArrayList<>();
        strings2.add("a");
        strings2.add("b");
        strings2.add("a");
        List<Object> collect1 = Stream.of(strings, strings2).flatMap(Collection::stream).collect(Collectors.toList());
        log.info("collect:{}", collect);
        log.info("size:{};collect1:{}", collect1.size(), collect1);
    }

5.skip和limit

 /**
     * skip,跳过前n个数据;limit,限制从流中获得前n个数据
     */
    @Test
    public void testSkip() {
        String[] arr = {"1", "22", "2233", "3", "5"};
        List<String> collect = Arrays.stream(arr).skip(1).limit(3).collect(Collectors.toList());
        log.info("collect:{}", collect);
    }

6.聚合操作

/**
     * 聚合操作
     */
    @Test
    public void polymerization() {
        String[] arr = {"ax", "abb", "bccc", "cdddd"};
        //获取最大值
        Stream.of(arr).max(Comparator.comparing(String::length)).ifPresent(System.out::println);
        //获取最小值
        Stream.of(arr).min(Comparator.comparing(String::length)).ifPresent(System.out::println);
        //获取数量
        log.info("cunt:{}", Stream.of(arr).count());
        //获取长度>1的第一个 如果没有符合条件的数据 就返回other
        String str = Stream.of(arr).parallel().filter(x -> x.length() > 1).findFirst().orElse("other");
        log.info("str:{}", str);

        //findAny  找到所有匹配的元素,对并行流十分有效, 只要在任何片段发现了第一个匹配元素就会结束整个运算
        Optional<String> any = Stream.of(arr).parallel().filter(x -> x.length() > 1).findAny();
        log.info("any:{}", JSON.toJSONString(any));

        //anyMatch 是否含有匹配元素
        Boolean aBoolean = Stream.of(arr).anyMatch(x -> x.startsWith("a"));
        log.info("aBoolean:{}", aBoolean);
    }

7.聚合计算

  /**
     * 聚合计算
     */
    @Test
    public void calculation() {
        List<Person> personList = new ArrayList<>();
        personList.add(new Person("小明", 10));
        personList.add(new Person("小皇", 20));
        personList.add(new Person("小菜", 30));
        personList.add(new Person("小红", 40));
        IntSummaryStatistics summaryStatistics = personList.stream().collect(Collectors.summarizingInt(Person::getAge));
        log.info("getAverage->{}", summaryStatistics.getAverage());//平均值
        log.info("getMax->{}", summaryStatistics.getMax());//最大值
        log.info("getMin->{}", summaryStatistics.getMin());//最小值
        log.info("getCount->{}", summaryStatistics.getCount());//数量
        log.info("getSum->{}", summaryStatistics.getSum());//累加
    }

8.并行

在 Java 8 中, 集合接口有两个方法来生成流: stream() − 为集合创建串行流。 parallelStream() − 为集合创建并行流。

有时候parallelStream创建并行流失败 可以考虑使用一下方式

 

测试并发以及普通的效率(并且次数越多-差距越大)

/**
     * 测试 并发  每个执行  99999999*4次
     */
    @Test
    public void parallel() {
        List<Person> personList = new ArrayList<>();
        personList.add(new Person("小明", 10));
        personList.add(new Person("小皇", 20));
        personList.add(new Person("小菜", 30));
        personList.add(new Person("小红", 40));
        List<Person> personListx = new ArrayList<>();


        //region 并发
        Long startTime = System.currentTimeMillis();
        List<Object> collect = personList.stream().parallel().map(c -> {
            for (int i = 0; i < 99999999; i++) {
                String name = i + "";
                new Person(name, i);
            }
            return null;
        }).collect(Collectors.toList());
        Long endTime = System.currentTimeMillis();
        log.info("并发耗时:{}", endTime - startTime);
        //endregion

        //region 普通
        Long startTime2 = System.currentTimeMillis();
        for (Person person : personList) {
            for (int i = 0; i < 99999999; i++) {
                String name = i + "";
                new Person(name, i);
            }
        }
        Long endTime2 = System.currentTimeMillis();
        log.info("普通耗时2:{}", endTime2 - startTime2);
        //endregion
    }

 

 

3.拓展

3.1除了lamda表达式筛选数据外,还有一种 不过感觉没有lamda简洁,此处只是作为了解一下

   public List<Brand> list(Map<String, Object> searchMap) {
        Example example = new Example(Brand.class);
        //封装查询条件
        Example.Criteria criteria = example.createCriteria();
        if (searchMap!=null){
            //品牌名称(模糊) like  %
            if (searchMap.get("name")!=null && !"".equals(searchMap.get("name"))){
                criteria.andLike("name","%"+searchMap.get("name")+"%");
            }
            //按照品牌首字母进行查询(精确)
            if (searchMap.get("letter")!=null && !"".equals(searchMap.get("letter"))){
                criteria.andEqualTo("letter",searchMap.get("letter"));
            }
        }
        List<Brand> brandList = brandMapper.selectByExample(example);
        return brandList;
    }

 

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值