java8新特性

本文涉及的产品
云数据库 Redis 版,社区版 2GB
推荐场景:
搭建游戏排行榜
简介: java8新特性

一.JDK8 的增强

1.jdk8 增强与新特性

Java 8 引入了许多新的语言特性和 API 改进,以下是其中一些主要的特性:

  1. Lambda 表达式: Lambda 表达式是一种更简洁的语法,用于表示一个匿名函数。它使得在集合操作、事件处理等场景下代码更具可读性和简洁性。
  2. 函数式接口: Java 8 引入了函数式接口的概念,这是只包含一个抽象方法的接口。Lambda 表达式可以与函数式接口一起使用。
  3. 方法引用: 方法引用允许你直接引用现有的方法或构造函数,从而使代码更加简洁。
  4. 默认方法和静态方法: 接口现在可以包含默认方法和静态方法的实现。这使得在接口中添加新的方法时,不会破坏已有的实现。
  5. Stream API: Stream API 提供了一种更便捷的方式来处理集合数据。它支持函数式编程风格,可以用于过滤、映射、归约等操作。
  6. 新的日期和时间 API: Java 8 引入了 java.time 包,提供了全新的日期和时间 API,解决了旧的 DateCalendar 类存在的问题。
  7. Optional 类:Optional 是一个容器类,用于表示一个值可能存在,也可能不存在的情况,从而减少空指针异常的发生。
  8. Nashorn 引擎: Nashorn 是一个新的轻量级、高性能的 JavaScript 引擎,用于在 Java 程序中执行 JavaScript 代码。
  9. 新的重复注解和类型注解: 如前所述,Java 8 引入了对多重注解的支持,以及更丰富的类型注解。
  10. PermGen 空间被移除: Java 8 中,永久代(PermGen)被元空间(Metaspace)所取代,用于存放类的元数据。

2.Stream 的组成与特点

Stream(流)是一个来自数据源的元素队列并支持聚合操作:

  • 元素是特定类型的对象,形成一个队列。Java中的Stream不会向集合那样存储和管理元素,而是按需计算
  • 数据源流的来源可以是集合Collection、数组ArrayI/O channel, 产生器generator
  • 聚合操作类似SQL语句一样的操作, 比如filter, map, reduce, find, match, sorted

和以前的Collection操作不同, Stream 操作还有两个基础的特征:

  • Pipelining: 中间操作都会返回流对象本身。这样多个操作可以串联成一个管道, 如同流式风格(fluent style)。这样做可以对操作进行优化, 比如延迟执行(laziness evaluation)和短路( short-circuiting)
  • 内部迭代:以前对集合遍历都是通过Iterator或者For-Each的方式, 显式的在集合外部进行迭代, 这叫做外部迭代。Stream提供了内部迭代的方式, 通过访问者模式 (Visitor)实现。

和迭代器又不同的是,Stream 可以并行化操作,迭代器只能命令式地、串行化操作。顾名思义,当使用串行方式去遍历时,每个 item 读完后再读下一个 item。而使用并行去遍历时,数据会被分成多个段,其中每一个都在不同的线程中处理,然后将结果一起输出。

3.Stream 底层原理

示例代码:

public class Java8_01_Source_Main {


   public static void main(String[] args) {

       List<String> list = new ArrayList<>();

       list.add("Red");

       list.add("Green");

       list.add("Blue");

       long lengthyColors = list.stream().filter(c -> c.length() > 3).count();

       System.out.println(lengthyColors);

   }


}

javap -c -p Java8_01_Source_Main  查看class文件

> javap -c -p  Java8_01_Source_Main

警告: 二进制文件Java8_01_Source_Main包含com.xiaofei.antjava8.源码.Java8_01_Source_Main

Compiled from "Java8_01_Source_Main.java"

public class com.xiaofei.antjava8.源码.Java8_01_Source_Main {

 public com.xiaofei.antjava8.源码.Java8_01_Source_Main();

   Code:

      0: aload_0

      1: invokespecial #1                  // Method java/lang/Object."<init>":()V

      4: return


 public static void main(java.lang.String[]);

   Code:

      0: new           #2                  // class java/util/ArrayList

      3: dup

      4: invokespecial #3                  // Method java/util/ArrayList."<init>":()V

      7: astore_1

      8: aload_1

      9: ldc           #4                  // String Red

     11: invokeinterface #5,  2            // InterfaceMethod java/util/List.add:(Ljava/lang/Object;)Z

     16: pop

     17: aload_1

     18: ldc           #6                  // String Green

     20: invokeinterface #5,  2            // InterfaceMethod java/util/List.add:(Ljava/lang/Object;)Z

     25: pop

     26: aload_1

     27: ldc           #7                  // String Blue

     29: invokeinterface #5,  2            // InterfaceMethod java/util/List.add:(Ljava/lang/Object;)Z

     34: pop

     35: aload_1

     36: invokeinterface #8,  1            // InterfaceMethod java/util/List.stream:()Ljava/util/stream/Stream;

     41: invokedynamic #9,  0              // InvokeDynamic #0:test:()Ljava/util/function/Predicate;

     46: invokeinterface #10,  2           // InterfaceMethod java/util/stream/Stream.filter:(Ljava/util/function/Predicate;)Ljava/util/stream/Stream;

     51: invokeinterface #11,  1           // InterfaceMethod java/util/stream/Stream.count:()J

     56: lstore_2

     57: getstatic     #12                 // Field java/lang/System.out:Ljava/io/PrintStream;

     60: lload_2

     61: invokevirtual #13                 // Method java/io/PrintStream.println:(J)V

     64: return


 private static boolean lambda$main$0(java.lang.String);  // c -> c.length() > 3

   Code:

      0: aload_0

      1: invokevirtual #14                 // Method java/lang/String.length:()I

      4: iconst_3

      5: if_icmple     12

      8: iconst_1

      9: goto          13

     12: iconst_0

     13: ireturn

}

分析结论:

通过字节码可以看到 invokedynamic 指令以某种方式负责创建 Predicate 实例。

此方法以 字符串 作为输入,然后执行以下步骤:

  • 计算输入长度(invokevirtual on length)
  • 将长度与常量 3 进行比较(if_icmple 和 iconst_3)
  • 如果长度小于或等于 3,则返回 false

Java 7 中之前,JVM 只是有四个方法调用类型:

  • invokevirtual 调用正常类方法,
  • invokestatic 调用静态方法,
  • invokeinterface 调用接口的方法,
  • invokespecial 调用构造函数或私有方法。

对于 lambda 表达式,Java 不是在编译时创建匿名内部类,而是在运行时通过调用动态创建它们

4.回调函数

#回调函数的写法  有套路的

#消息确认成功回调函数

ConfirmCallback ackCallback (deliveryTag,multiple)->{

}:

#消息确认失败回调函数

ConfirmCallback nackCallback (deliveryTag,multiple)->(

#准备消息的监听器监听哪些消息成功了哪些消息失败了

#异步通知

channel..addConfirmListener(ackCallback,nackCallback);

5.flatMap

public static void main(String[] args) {

       List<Integer> lista = new ArrayList<>();

       lista.add(1);

       lista.add(3);


       List<Integer> listb = new ArrayList<>();

       listb.add(2);

       listb.add(4);

       List<List<Integer>> listc = new ArrayList<>();

       listc.add(lista);

       listc.add(listb);

       System.out.println(listc);

       List<Integer> listd = listc.stream().flatMap(ele -> ele.stream()).collect(Collectors.toList());

       System.out.println(listd);

   }

Map<String,List<Object>>使用java8转为 List<Object>

public static void main(String[] args) {

       Map<String, List<Integer>> map = new HashMap<>();

       map.put("1", Arrays.asList(1, 2, 3));

       map.put("2", Arrays.asList(4, 5, 6));

       map.put("3", Arrays.asList(7, 8, 9));

       // 假设已经将数据存储到map中

       List<Integer> list = map.values().stream()

               .flatMap(List::stream)

               .collect(Collectors.toList());

       // 将所有List<Object>对象中的元素合并成一个Stream,并将所有元素收集到一个新的List<Object>中

       log.info(list.toString());

   }

final List<StoreSkuInvSalDTO> collect = groupName_2_salDatas.values().stream()

               .flatMap(x -> x.getProducts().stream())

               .collect(Collectors.toList());

二.筛选

1.筛选是否存在

 final boolean exist = value.stream()

                   .filter(x -> x.getFlag().equals(FlagEnum.RED.getCode())).collect(Collectors.toList()).size() > 0;

2.去重

//方式一

List<Long> distinctIdList = idList.stream().distinct().collect(Collectors.toList());

//方式二

final List<ProductAllexinfoV1DTO> invSqlSkus = tags.stream().filter(t -> t.getInvQty() > 0 || t.getSalQty() > 0).collect(Collectors.toList());

       homeSkuTotal.setProductTotal(CollectionUtils.isEmpty(invSqlSkus) ? 0 :

               invSqlSkus.stream().map(ProductAllexinfoV1DTO::getProductKey).collect(Collectors.toSet()).size());

3.最小最大

//最小值

final Integer minWeek = timeAxisDTOS.stream().min(Comparator.comparing(x -> x.getFinancialWeek())).get().getFinancialWeek();


//最大值

final Integer maxWeek = timeAxisDTOS.stream().max(Comparator.comparing(x -> x.getFinancialWeek())).get().getFinancialWeek();

4.找到第一个存在的

final Optional<AdsDimFinancialYearWeekInfoDO> first = dimList.stream().filter(t -> t.getFinancialYear().equals(finalYear)&& t.getFinancialYearWeek().equals(finalWeek)).findFirst();

if (first.isPresent()) {

final AdsDimFinancialYearWeekInfoDO yearWeekInfo = first.get();

}

5.并且筛选

final Set<String> headerFilterList = pageQuery.getHeaderFilterList();

       if (CollectionUtils.isNotEmpty(headerFilterList)) {

           tags = tags.stream().filter(t -> headerFilterList.contains("salQty") ? t.getSalQty() > 0 : true)

                   .filter(t -> headerFilterList.contains("replenishQty") ? t.getReplenishQty() > 0 : true)

                   .filter(t -> headerFilterList.contains("orderNotArriveQty") ? t.getOrderNotArriveQty() > 0 : true)

                   .filter(t -> headerFilterList.contains("replenishNotArriveQty") ? t.getReplenishNotArriveQty() > 0 : true)

                   .collect(Collectors.toList());

       }

6.模糊筛选

final String productCode = pageQuery.getProductCode();

       if (StringUtils.isNotEmpty(productCode)) {

           tags = tags.stream().filter(t -> t.getProductCode() != null && t.getProductCode().indexOf(productCode) > -1).collect(Collectors.toList());

       }

7.或者筛选

final Set<String> invQtyList = pageQuery.getInvQtyList();

       if (CollectionUtils.isNotEmpty(invQtyList)) {

           if (!invQtyList.contains("A") && !invQtyList.contains("B") && invQtyList.contains("C") && invQtyList.contains("D")) {

               tags = tags.stream().filter(t -> t.getInvQty() >= 50)

                       .collect(Collectors.toList());

           } else {

               tags = tags.stream().filter(t ->

                       (invQtyList.contains("A") && t.getInvQty() <= 0) ||

                               (invQtyList.contains("B") && t.getInvQty() > 0 && t.getInvQty() < 50) ||

                               (invQtyList.contains("C") && t.getInvQty() > 50 && t.getInvQty() < 300) ||

                               (invQtyList.contains("D") && t.getInvQty() >= 300)


               ).collect(Collectors.toList());

           }

       }

8.找到最近一天

final Optional<CityAndRegionAndCountryBrandSkuRepDTO> max = orrSkus.stream().filter(t ->

                               StringUtils.isNotEmpty(t.getPeriod_sdate()) && StringUtils.isNotEmpty(skuRep.getPeriod_sdate()) &&              DateTimeUtils.dateDiff(DateTimeUtils.str2Date(t.getPeriod_sdate()), DateTimeUtils.str2Date(skuRep.getPeriod_sdate())) > 0)                  .max(Comparator.comparing(CityAndRegionAndCountryBrandSkuRepDTO::getPeriod_sdate));

                       if (max.isPresent()) {

                           final CityAndRegionAndCountryBrandSkuRepDTO periodSdateOrr = max.get();}

9.反射筛选

final Set<String> headerFilterList = pageQuery.getHeaderFilterList();

       if (CollectionUtils.isNotEmpty(headerFilterList) && !headerFilterList.contains(CommonConstant.ALL)) {

           for (String item : headerFilterList) {

               if (StringUtils.equals("replenishQty", item) || StringUtils.equals("orderNotArriveQty", item) || StringUtils.equals("replenishNotArriveQty", item)) {

                   tags = tags.stream().filter(t -> Objects.nonNull(Reflect.on(t).field(item).get()) && (Integer) Reflect.on(t).field(item).get() != 0).collect(Collectors.toList());

               } else {

                   tags = tags.stream().filter(t -> Objects.nonNull(Reflect.on(t).field(item).get()) && (Integer) Reflect.on(t).field(item).get() > 0).collect(Collectors.toList());

               }

           }

       }

10.filter 过滤

//筛选符合条件的数据

List<DdlNode> collect = dagConf.getNodes().stream().filter(t -> NodeTypeEnum.OUT.name().equalsIgnoreCase(t.getType()))

   .collect(Collectors.toList());

//或者条件

storeDay += dayStoreSkuSizeInvSalDTOList.stream().filter(p1 -> p1.getFlag() == 1 || p1.getFlag() == 3).count();

//并且条件

storeDay += dayStoreSkuSizeInvSalDTOList.stream().filter(p1 -> p1.getFlag() == 1 && p1.getFlag() == 3).count();

11.条件成立才过滤

products = products.stream()

                       .filter(x -> StringUtils.equals(x.getCategoryName1(), categoryName1))

                       .filter(x -> StringUtils.isEmpty(genderName) || StringUtils.equals(x.getGenderName(), genderName))

                       .filter(x -> StringUtils.equals(x.getIsnewFlag(), "0"))

                       .collect(Collectors.toList());

12.list 是否重复

public class Java8_13_stream_count {

 public static void main(String[] args) {

   List<Integer> list = new ArrayList() {

     {

       add(1);

       add(2);

       add(1);

     }

   };

   long count = list.stream().distinct().count();

   boolean isRepeat = count < list.size();

   System.out.println(count);//输出2

   System.out.println(isRepeat);//输出true

 }

}

13.判断相同的元素

public class Java8_06_Stream_Same {

 public static void main(String[] args) {

   // 老师集合

   List<Teacher> teachers = Arrays.asList(

     new Teacher(1L, "张三"),

     new Teacher(2L, "李四"),

     new Teacher(3L, "王五"),

     new Teacher(4L, "赵六"));


   // 学生集合

   List<Student> students = Arrays.asList(

     new Student(5L, "张三"),

     new Student(6L, "李四"),

     new Student(7L, "小红"),

     new Student(8L, "小明"));


   // 求同时出现在老师集合和学生集合中的人数,name相同即视为同一个人

   int size = (int) teachers.stream()

     .map(t -> students.stream().filter(s -> Objects.nonNull(t.getName()) && Objects.nonNull(s.getName()) && Objects.equals(t.getName(), s.getName())).findAny().orElse(null))

     .filter(Objects::nonNull).count();


   // 求同时出现在老师集合和学生集合中人的name集合,name相同即视为同一个人

   List<String> names = teachers.stream()

     .map(t -> students.stream().filter(s -> Objects.nonNull(t.getName()) && Objects.nonNull(s.getName()) && Objects.equals(t.getName(), s.getName())).findAny().orElse(null))

     .filter(Objects::nonNull)

     .map(Student::getName)

     .collect(Collectors.toList());


   System.out.println("相同的人数:" + size);

   System.out.println("相同的人姓名集合:" + names);

 }

}

14.Match

  • anyMatch: 匹配到任何一个元素和指定的元素相等,返回 true
  • allMatch():匹配到全部元素和指定的元素相等,返回 true
  • noneMatch():与 allMatch() 效果相反

List<String> strList = ListUtil.toList("a", "b", "c", "d");

       boolean a = Optional.ofNullable(strList).orElseGet(ListUtil::toList)

               .stream()

               .anyMatch(obj -> obj.equals("a"));

       System.out.println("anyMatch()测试多元素结果:" + a);

三.排序

1.单排序

properties.sort(Comparator.comparing(x -> x.distance));

list.sort(Comparator.comparing(UserInformation::getName));


//正序

list=list.stream().sorted().collect(Collectors.toList());

list.stream().sorted(Comparator.comparing(Student::getAge))


//逆序

list.stream().sorted(Comparator.reverseOrder())

list.stream().sorted(Comparator.comparing(Student::getAge).reversed())

2.双排序

timeAxisList.sort(Comparator.comparing(TimeAxisDTO::getFinancialYear).thenComparing(TimeAxisDTO::getFinancialWeek));

多字段排序:

list.sort(Comparator.comparing(UserInformation::getId).thenComparing(UserInformation::getAge));

多字段排序,指定正序还是倒序:

/**

    * 按照推荐、置顶、发布时间来排序

    * @param list

    */

private static void sort(List<Article> list){

   List<Article> sortList = list.stream()            .sorted(Comparator.comparing(Article::getRecommend,Comparator.reverseOrder())

                   .thenComparing(Article::getTop,Comparator.reverseOrder())

                   .thenComparing(Article::getReleaseTime,Comparator.reverseOrder()))

           .collect(Collectors.toList());

   sortList.stream().forEach(System.out::println);

}

3.自定义排序

List<String> sortListA = Arrays.asList("2023", "2022", "2021", "2020", "2019", "2018", "2017");

List<String> sortListB = Arrays.asList("春", "夏", "秋", "冬");

value = value.stream().sorted(Comparator.comparing(TotalListRegionSeasonDTO::getRegionNo, Comparator.comparing(sortListA::indexOf))

                       .thenComparing(TotalListRegionSeasonDTO::getSeasonName, Comparator.comparing(sortListB::indexOf))).collect(Collectors.toList());

4.反转排序

salListsTopN.sort(Comparator.comparing(SalList::getSalQty).reversed());

5.中文拼音排序

List<String> sortList = Arrays.asList("春", "夏", "秋", "冬");

Collator collator = Collator.getInstance(Locale.CHINA);

styleCategoryDim = styleCategoryDim.stream().sorted(Comparator.comparing(StyleCategoryDataDTO::getSeasonName, Comparator.comparing(sortList::indexOf))

.thenComparing(StyleCategoryDataDTO::getStyleCategoryName, collator)).collect(Collectors.toList());

6.list 嵌套排序

List<List<String>>排序

/**

* List<List<String>> 排序算法

*

* @author : qinyingjie

* @version : 2.2.0

* @date : 2022/12/12 11:22

*/

public class Java8_09_stream_sort {


   private static List<List<String>> METHOD_LIST_WITH_ORDER = new LinkedList<>();


   /**

    * 按第n位降序排列

    *

    * @param compareIndex

    */

   private static void doSortDesc(int compareIndex) {

       for (int i = 0; i < METHOD_LIST_WITH_ORDER.size() - 1; i++) {

           int preIndex = i;

           int currentIndex = i + 1;

           Long currentItem = Long.valueOf(METHOD_LIST_WITH_ORDER.get(currentIndex).get(compareIndex));

           List<String> currentObject = METHOD_LIST_WITH_ORDER.get(currentIndex);


           //当前节点的值大于前一节点,交换,且是循环比较

           while (preIndex >= 0 && currentItem > Long.valueOf(METHOD_LIST_WITH_ORDER.get(preIndex).get(compareIndex))) {

               METHOD_LIST_WITH_ORDER.set(preIndex + 1, METHOD_LIST_WITH_ORDER.get(preIndex));

               preIndex--;

           }

           //设置preIndex + 1的值

           METHOD_LIST_WITH_ORDER.set(preIndex + 1, currentObject);

       }

   }


   public static void main(String[] args) {

       METHOD_LIST_WITH_ORDER.add(Arrays.asList("1", "3", "4", "5"));

       METHOD_LIST_WITH_ORDER.add(Arrays.asList("1", "3", "4", "4"));

       METHOD_LIST_WITH_ORDER.add(Arrays.asList("1", "3", "4", "7"));

       METHOD_LIST_WITH_ORDER.add(Arrays.asList("1", "3", "4", "1"));

       METHOD_LIST_WITH_ORDER.add(Arrays.asList("2", "3", "4", "9"));

       doSortDesc(3);

       for (List<String> list : METHOD_LIST_WITH_ORDER) {

           for (String s : list) {

               System.out.print(s + ",");

           }

           System.out.println();

       }

       System.out.println(JSON.toJSONString(METHOD_LIST_WITH_ORDER));

   }

}

7.多字段升降不定

final String sortName = pageQuery.getSortname();

       final String sortOrd = pageQuery.getSortord();

       tags = tags.stream().sorted(

               ("sal_qty".equals(sortName) ? Comparator.comparing(ProductAllexinfoV1DTO::getSalQty, StringUtils.equals(sortOrd, "desc") ? Comparator.reverseOrder() : Comparator.naturalOrder()) :

                       "total7_sal_qty".equals(sortName) ? Comparator.comparing(ProductAllexinfoV1DTO::getTotal7SalQty, StringUtils.equals(sortOrd, "desc") ? Comparator.reverseOrder() : Comparator.naturalOrder()) :

                               "total14_sal_qty".equals(sortName) ? Comparator.comparing(ProductAllexinfoV1DTO::getTotal14SalQty, StringUtils.equals(sortOrd, "desc") ? Comparator.reverseOrder() : Comparator.naturalOrder()) :

                                       "total28_sal_qty".equals(sortName) ? Comparator.comparing(ProductAllexinfoV1DTO::getTotal28SalQty, StringUtils.equals(sortOrd, "desc") ? Comparator.reverseOrder() : Comparator.naturalOrder()) :

                                               "total_sal_qty".equals(sortName) ? Comparator.comparing(ProductAllexinfoV1DTO::getTotalSalQty, StringUtils.equals(sortOrd, "desc") ? Comparator.reverseOrder() : Comparator.naturalOrder()) :

                                                       "total_size_store_day".equals(sortName) ? Comparator.comparing(ProductAllexinfoV1DTO::getTotalSizeStoreDay, StringUtils.equals(sortOrd, "desc") ? Comparator.reverseOrder() : Comparator.naturalOrder()) :

                                                               "counter_date".equals(sortName) ? Comparator.comparing(ProductAllexinfoV1DTO::getCounterDate, StringUtils.equals(sortOrd, "desc") ? Comparator.reverseOrder() : Comparator.naturalOrder()) :

                                                                       "inv_store_count".equals(sortName) ? Comparator.comparing(ProductAllexinfoV1DTO::getInvStoreCount, StringUtils.equals(sortOrd, "desc") ? Comparator.reverseOrder() : Comparator.naturalOrder()) :

                                                                               "total_sal_qty_store_rate".equals(sortName) ? Comparator.comparing(ProductAllexinfoV1DTO::getTotalSalQtyStoreRate, StringUtils.equals(sortOrd, "desc") ? Comparator.reverseOrder() : Comparator.naturalOrder()) :

                                                                                       "total30_sal_qty_store_rate".equals(sortName) ? Comparator.comparing(ProductAllexinfoV1DTO::getTotal30SalQtyStoreRate, StringUtils.equals(sortOrd, "desc") ? Comparator.reverseOrder() : Comparator.naturalOrder()) :

                                                                                               "replenish_not_arrive_qty".equals(sortName) ? Comparator.comparing(ProductAllexinfoV1DTO::getReplenishNotArriveQty, StringUtils.equals(sortOrd, "desc") ? Comparator.reverseOrder() : Comparator.naturalOrder()) :

                                                                                                       Comparator.comparing(ProductAllexinfoV1DTO::getSalQty, StringUtils.equals(sortOrd, "desc") ? Comparator.reverseOrder() : Comparator.naturalOrder()))

       ).collect(Collectors.toList());

8.含空值排序

list=list.stream().sorted(Comparator.comparing(l -> l.getCreateTime(), Comparator.nullsFirst(Date::compareTo))).collect(Collectors.toList());


List<Map<String, Object>> collect = maps.stream() .sorted(Comparator.comparing((Map<String, Object> o) -> (Double) o.get("score"),

Comparator.nullsLast(Comparator.reverseOrder()))

.thenComparing((Map<String, Object> o) -> ((double) o.get("dealerDistance")),

Comparator.nullsLast(Comparator.naturalOrder())))

.collect(Collectors.toList());

9.反射排序

public static void main(String[] args) {

       final String sortName = "counterDate";

//        final String sortOrd = "desc";

       final String sortOrd = "asc";


       List<ProductAllexinfoV1DTO> tags = new ArrayList<>();

       ProductAllexinfoV1DTO do1 = new ProductAllexinfoV1DTO();

       do1.setSalQty(26);

       do1.setCounterDate("2023-01-01");

       tags.add(do1);


       ProductAllexinfoV1DTO do2 = new ProductAllexinfoV1DTO();

       do2.setSalQty(233);

       do2.setCounterDate(null);

       tags.add(do2);


       ProductAllexinfoV1DTO do3 = new ProductAllexinfoV1DTO();

       do3.setSalQty(56);

       do3.setCounterDate("2023-03-01");

       tags.add(do3);


       tags.sort((o1, o2) -> {

           final Object object1 = Reflect.on(o1).field(sortName).get();

           final Object object2 = Reflect.on(o2).field(sortName).get();

          if (Objects.isNull(object1) && Objects.isNull(object2)) return 0;

           if (Objects.isNull(object1)) return 1;

           if (Objects.isNull(object2)) return -1;

           if (object1 instanceof String) {

               return StringUtils.equals(sortOrd, "desc") ? Comparator.<String>reverseOrder().compare((String) object1, (String) object2) :

                       Comparator.<String>naturalOrder().compare((String) object1, (String) object2);

           } else if (object1 instanceof Integer) {

               return StringUtils.equals(sortOrd, "desc") ? Comparator.<Integer>reverseOrder().compare((Integer) object1, (Integer) object2) :

                       Comparator.<Integer>naturalOrder().compare((Integer) object1, (Integer) object2);

           } else if (object1 instanceof BigDecimal) {

               return StringUtils.equals(sortOrd, "desc") ? Comparator.<BigDecimal>reverseOrder().compare((BigDecimal) object1, (BigDecimal) object2) :

                       Comparator.<BigDecimal>naturalOrder().compare((BigDecimal) object1, (BigDecimal) object2);

           }

           return 0;

       });

       System.out.println(JSONArray.toJSONString(tags));

   }

测试filter:

public static void main(String[] args) {

       final String sortName = "counterDate";

//        final String sortOrd = "desc";

       final String sortOrd = "asc";


       List<ProductAllexinfoV1DTO> tags = new ArrayList<>();

       ProductAllexinfoV1DTO do1 = new ProductAllexinfoV1DTO();

       do1.setSalQty(26);

       do1.setCounterDate("2023-01-01");

       do1.setReplenishQty(111);

       tags.add(do1);


       ProductAllexinfoV1DTO do2 = new ProductAllexinfoV1DTO();

       do2.setSalQty(233);

       do2.setCounterDate(null);

       do2.setReplenishQty(0);

       tags.add(do2);


       ProductAllexinfoV1DTO do3 = new ProductAllexinfoV1DTO();

       do3.setSalQty(56);

       do3.setCounterDate("2023-03-01");

       do3.setReplenishQty(131);

       tags.add(do3);


       final Set<String> headerFilterList = new HashSet<>();

       headerFilterList.add("replenishQty");

       if (CollectionUtils.isNotEmpty(headerFilterList) && !headerFilterList.contains(CommonConstant.ALL)) {

           for (String item : headerFilterList) {

               if (StringUtils.equals("replenishQty", item) || StringUtils.equals("orderNotArriveQty", item) || StringUtils.equals("replenishNotArriveQty", item)) {

                   tags.stream().filter(t -> Objects.nonNull(Reflect.on(t).field(item).get()) && (Integer) Reflect.on(t).field(item).get() != 0).collect(Collectors.toList());

               } else {

                   tags.stream().filter(t -> Objects.nonNull(Reflect.on(t).field(item).get()) && (Integer) Reflect.on(t).field(item).get() > 0).collect(Collectors.toList());

               }

           }

       }

       System.out.println(JSONArray.toJSONString(tags));

   }

10.不用 stream

// 正序

list.sort(Comparator.comparing(Integer::intValue));

// 倒序

list.sort(Comparator.comparing(Integer::intValue).reversed());

// 正序

list.sort(Comparator.comparing(Student::getAge));

// 倒序

list.sort(Comparator.comparing(Student::getAge).reversed());

11.nullsLast

以 nullsLast()为例,项目逻辑中 dealerDistance 为 null 时排最后

Comparator.nullsLast(Comparator.reverseOrder())把 null 排序最后面,然后是 Comparator.reverseOrder(),null 值不参与逆序,null 还是在最后Comparator.nullsLast(Double ::compareTo).reversed() 先是把 null 排最后面,再整体 reversed(),包括为 null 的,所以 null 在最前面注:reverseOrder()是逆转排序即逆序,而 reversed()是逆转仔细理解,这两个在意思上还是有区别

13.根据 map 的 key 排序

要根据resultsMap的键值对中的键(String类型)进行降序排列,可以使用Comparator接口来实现自定义比较器,并将其传递给TreeMap类的构造函数。以下是一种实现方法:

public class Main {

   public static void main(String[] args) {

       // 创建一个示例的 Map

       Map<String, List<StoreSalCalendarDTO>> resultsMap = new HashMap<>();

       // 添加一些键值对

       resultsMap.put("Key1", new ArrayList<>());

       resultsMap.put("Key3", new ArrayList<>());

       resultsMap.put("Key2", new ArrayList<>());

       // 使用自定义比较器对键进行降序排列

       Map<String, List<StoreSalCalendarDTO>> sortedMap = new TreeMap<>(new KeyComparator());

       sortedMap.putAll(resultsMap);

       // 打印排好序的 Map

       for (Map.Entry<String, List<StoreSalCalendarDTO>> entry : sortedMap.entrySet()) {

           System.out.println(entry.getKey());

       }

   }


   static class KeyComparator implements Comparator<String> {

       @Override

       public int compare(String key1, String key2) {

           // 降序排列

           return key2.compareTo(key1);

       }

   }

}

在上述示例中,我们首先创建了一个示例的resultsMap,其中包含一些键值对。然后,我们定义了一个名为KeyComparator的内部类,实现了Comparator<String>接口,用于比较键的值。在compare方法中,我们通过使用key2.compareTo(key1)实现了降序排列。最后,我们创建了一个新的TreeMap实例,并传递了KeyComparator对象作为参数。通过putAll方法将原始的resultsMap中的键值对放入新的sortedMap中,以得到降序排列的结果。

在打印循环中,我们遍历排好序的sortedMap的键,并将它们输出到控制台。

14.set 排序

storeSkuSizeInvTotalSalDTO.setSizeCodeList(new TreeSet<>(sizeCodes));

15.比较器特性

特殊错误:比较方法违反其一般合同

在 JDK7 版本以上,Comparator 要满足自反性,传递性,对称性,不然 Arrays.sort,Collections.sort会报 IllegalArgumentException 异常。

  • 自反性:当 两个相同的元素相比时,compare 必须返回 0,也就是 compare(o1, o1) = 0;
  • 反对称性:如果 compare(o1,o2) = 1,则 compare(o2, o1)必须返回符号相反的值也就是 -1;
  • 传递性:如果 a>b, b>c, 则 a 必然大于 c。也就是 compare(a,b)>0, compare(b,c)>0, 则 compare(a,c)>0

final Object object1 = Reflect.on(o1).field(sortName).get();

final Object object2 = Reflect.on(o2).field(sortName).get();

if (Objects.isNull(object1) && Objects.isNull(object2)) return 0;

if (Objects.isNull(object1)) return 1;

if (Objects.isNull(object2)) return -1;

四.互转

1.抽取对象属性

List<Integer> ids = taskRecordDOList.stream().map(TaskRecordDO::getId).collect(Collectors.toList());

2.对象互转

List<DayStoreSkuSizeInvSalDTO> dtos = sizeInvSalList.stream()

               .map(item -> {

                   DayStoreSkuSizeInvSalDTO dayStoreSkuSizeInvSalDTO = new DayStoreSkuSizeInvSalDTO();

                   BeanUtil.copyProperties(item, dayStoreSkuSizeInvSalDTO);

                   return dayStoreSkuSizeInvSalDTO;

               }).collect(Collectors.toList());

3.属性转 set

转set:

final Set<String> sizeCodes = sizeInvSalList.stream().map(DayStoreSkuSizeInvSalDO::getSizeCode).collect(Collectors.toSet());

筛选转set:

final List<String> genderName = pageQuery.getGenderName();

       if (CollectionUtils.isNotEmpty(genderName)) {

           tags = tags.stream().filter(t -> genderName.contains(t.getGenderName()))

                   .collect(Collectors.toList());

       }

4.分组转 map

Map<Integer, List<TimeAxisDTO>> yearLists = list.stream().collect(Collectors.groupingBy(TimeAxisDTO::getFinancialYear));

//多字段

Map<String, List<DayStoreSkuSizeInvSalDTO>> financialYearWeekInfo = sizeIndex.stream().collect(Collectors.groupingBy(p -> p.getFinancialYear() + ":" + p.getFinancialWeek()));

每个店铺的价格等级:

@Test

public void test12() {

   //获取每个店铺的价格等级

   Map<String, Integer> map = properties.stream()

       .collect(Collectors.toMap(Property::getName, Property::getPriceLevel));

   System.out.println(JSON.toJSONString(map));

}


@Test

public void test13() {

   //所有价格等级的店铺列表

   Map<Integer, List<Property>> priceMap = properties.stream()

       .collect(Collectors.groupingBy(Property::getPriceLevel));

   System.out.println(JSON.toJSONString(priceMap));

}

5.list 转 list

Map<Object, List<Student>> mapGroup = list.stream().collect(Collectors.groupingBy(v ->             v.getName() + v.getAge()));

List<List<Student>> categorys = new ArrayList<>(mapGroup.values());

6.分组转 map

Map<String, List<TaskRecordDO>> collect1 = list.stream().collect(Collectors.groupingBy(TaskRecordDO::getOutNodeKey));

7.驼峰下划线

Gauva:

//驼峰转下划线

String ans = CaseFormat.LOWER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, "helloWorld");

System.out.println(ans);

//下划线转驼峰

String ans2 = CaseFormat.LOWER_UNDERSCORE.to(CaseFormat.LOWER_CAMEL, "hello_world");

System.out.println(ans2);

Hutool:

String ans = StrUtil.toCamelCase("hello_world");

System.out.println(ans);

String ans2 = StrUtil.toUnderlineCase("helloWorld");

System.out.println(ans2);

实战:

//排序:驼峰转下划线

String sortname = query.getSortname();

if (StringUtils.isNotEmpty(sortname)) {

   try {

       BrandStoreSkuInvSalRateWeekDTO.class.getField(sortname);

       sortname = CaseFormat.LOWER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, sortname);

       query.setSortname(sortname);

   } catch (NoSuchFieldException e) {

       log.error("排序字段不存在,排序字段为{}", sortname);

       query.setSortname(null);

   }

}

工具类:

public class ColumnUtil {

   private static Pattern humpPattern = Pattern.compile("[A-Z]");

   private static Pattern linePattern = Pattern.compile("_(\\w)");

   /**

    * 驼峰转下划线

    * @param str

    * @return

    */

   public static String humpToLine(String str) {

       Matcher matcher = humpPattern.matcher(str);

       StringBuffer sb = new StringBuffer();

       while (matcher.find()) {

           matcher.appendReplacement(sb, "_" + matcher.group(0).toLowerCase());

       }

       matcher.appendTail(sb);

       return sb.toString();

   }

   /**

    * 下划线转驼峰

    * @param str

    * @return

    */

   public static String lineToHump(String str) {

       str = str.toLowerCase();

       Matcher matcher = linePattern.matcher(str);

       StringBuffer sb = new StringBuffer();

       while (matcher.find()) {

           matcher.appendReplacement(sb, matcher.group(1).toUpperCase());

       }

       matcher.appendTail(sb);

       return sb.toString();

   }

}

8.toMap 重复 key

Map<Date, TimeAxisDTO> collect6 = timeAxisDTOListB.stream().collect(Collectors.

 toMap(TimeAxisDTO::getPeriodSdate, timeAxisDTO -> timeAxisDTO, (key1, key2) -> key1));

9.list 合并

/**

* 多个list合并

*

* @author : kwan

* @version : 1.0.0

* @date : 2022/8/9 10:33

*/

public class Java8_48_stream_merge_01 {

 public static void main(String[] args) {

   List<Person> personList = new ArrayList<>();

   personList.add(new Person("Sherry", 9000, 24, "female", "New York"));

   personList.add(new Person("Tom", 8900, 22, "male", "Washington"));

   personList.add(new Person("Jack", 9000, 25, "male", "Washington"));

   personList.add(new Person("Lily", 8800, 26, "male", "New York"));

   personList.add(new Person("Alisa", 9000, 26, "female", "New York"));

   List<Person> personList2 = new ArrayList<>();

   personList2.add(new Person("Sherry", 9000, 24, "female", "New York"));

   personList2.add(new Person("Tom", 8900, 22, "male", "Washington"));

   personList2.add(new Person("Jack", 9000, 25, "male", "Washington"));

   personList2.add(new Person("Lily", 8800, 26, "male", "New York"));

   personList2.add(new Person("Alisa", 9000, 26, "female", "New York"));

   List<List<Person>> list = new ArrayList<>();

   list.add(personList);

   list.add(personList2);

   List<Person> persons = merge(list);

   System.out.println(JSONArray.toJSONString(persons));

 }

 private static List<Person> merge(List<List<Person>> list) {

   List<Person> persons = new ArrayList<>();

   for (List<Person> people : list) {

     for (Person person : people) {

       persons.add(person);

     }

   }

   return persons;

 }

}

/**

* 多个list合并

*

* @author : kwan

* @version : 1.0.0

* @date : 2022/8/9 10:33

*/

public class Java8_48_stream_merge_02 {

   public static void main(String[] args) {

       List<Integer> list = ImmutableList.of(1, 3, 5);

       list = list.stream().flatMap(l -> {

           List<Integer> list1 = new ArrayList<>();

           list1.add(l + 1);

           list1.add(l + 2);

           return list1.stream();

       }).collect(Collectors.toList());

       System.out.println(list);// [2, 3, 4, 5, 6, 7]

   }

}

/**

* 多个list合并

*

* @author : kwan

* @version : 1.0.0

* @date : 2022/8/9 10:33

*/

public class Java8_48_stream_merge_03 {

   public static void main(String[] args) {

       List<List<Map<String, Object>>> lists = ImmutableList.of(

               ImmutableList.of(

                       ImmutableMap.of("a", 1, "b", 2), ImmutableMap.of("a", 2, "b", 3)

               ),

               ImmutableList.of(

                       ImmutableMap.of("a", 3, "b", 4), ImmutableMap.of("a", 4, "b", 5)

               ),

               ImmutableList.of(

                       ImmutableMap.of("a", 5, "b", 6), ImmutableMap.of("a", 6, "b", 7)

               )

       );

       // 将多个list合并为一个list

       List<Map<String, Object>> list = lists.stream().flatMap(Collection::stream).collect(Collectors.toList());

       System.out.println(JSONArray.toJSONString(list));

   }

}

10.数组转 List

/**

* 数组转list  Arrays.asList不能add

*

* @author : kwan

* @version : 1.0.0

* @date : 2022/8/10 00:21

*/

public class Basic_collection_10_Array2List_01 {


 public static void main(String[] args) {

   String[] strArray = new String[2];

   List list = Arrays.asList(strArray);

   //对转换后的list插入一条数据

   list.add("1");

   System.out.println(list);

 }

}

/**

* 数组转list

*

* @author : kwan

* @version : 1.0.0

* @date : 2022/8/10 00:21

*/

public class Basic_collection_10_Array2List_02 {

   public static void main(String[] args) {

       String[] strArray = new String[2];

       ArrayList<String> list = new ArrayList<String>(Arrays.asList(strArray));

       list.add("1");

       System.out.println(list);

   }

}

/**

* 数组转list

*

* @author : kwan

* @version : 1.0.0

* @date : 2022/8/10 00:21

*/

public class Basic_collection_10_Array2List_03 {


   public static void main(String[] args) {

       String[] strArray = new String[2];

       ArrayList< String> arrayList = new ArrayList<String>(strArray.length);

       Collections.addAll(arrayList, strArray);

       arrayList.add("1");

       System.out.println(arrayList);

   }

}

11.转对象

//转对象

Myclass myclass = JSONObject.parseObject(jsonStr , Myclass.class);// jsonStr 是String类型。

//转list对象

List<NewPxtOrder> pxtOrderList = JSONObject.parseArray(order,NewPxtOrder.class);

12.fastjson 不能转对象的情况

String redisKey = supplierRelateServiceManager.getRedisKey();

String checkOrderInfo = jedis.get(redisKey);

//  SelfOrderModel selfOrderModel = JSONObject.parseObject(checkOrderInfo, SelfOrderModel.class);

// selfOrderModel.setRejectReason(outExamineVo.getRemark());

JSONObject jsonObject = JSONObject.parseObject(checkOrderInfo);

jsonObject.put("rejectReason", outExamineVo.getRemark());

jedis.set(redisKey, jsonObject.toJSONString());

13.多字段分组

分组:

Map<Integer, Map<Integer, List<StoreSalCalendarDTO>>> groupByYearMonth =               results.stream().collect(Collectors.groupingBy(StoreSalCalendarDTO::getFinancialYear,                       Collectors.groupingBy(StoreSalCalendarDTO::getFinancialYearMonth)));

遍历:

Map<Integer, Map<Integer, List<StoreSalCalendarDTO>>> groupByYearMonth = new HashMap<>();

       if (Objects.nonNull(groupByYearMonth)) {

           groupByYearMonth.forEach((year, yearValue) -> {

               if (Objects.nonNull(yearValue)) {

                   yearValue.forEach((month, monthValue) -> {

                   });

               }

           });

       }

14.map 转 list

需要将 map 打平转为 list

 final List<StoreSkuInvSalDTO> sal = groupName_2_salDatas.values().stream()

               .flatMap(x -> x.getProducts().stream())

               .collect(Collectors.toList());

15.List、String、Set 互转

//list转string

String str= String.join("','", list);


//list转set

Set<String> set = new HashSet<>(skuList);


//set转list

List<String> list = new ArrayList<>(set);

五.计算

1.汇总数据

homeSkuTotal.setTotal7SalQty(tags.stream().mapToInt(item -> Objects.nonNull(item.getTotal7SalQty()) ? item.getTotal7SalQty() : 0).sum());

if (CollectionUtils.isNotEmpty(homeSkuTotalOrr)) {

     homeSkuTotalOrr.stream().mapToInt(AdsDayOrrDO::getOrderNotArriveQty).sum();

}

2.分组求和

分组求最大值再求和

if (CollectionUtils.isNotEmpty(homeSkuTotalOrr)) {

           final Collection<Optional<AdsDayOrrDO>> values = homeSkuTotalOrr.stream().collect(Collectors.groupingBy(AdsDayOrrDO::getProductKey, Collectors.maxBy(Comparator.comparing(AdsDayOrrDO::getPeriodSdate)))).values();

           homeSkuTotalDTO.setOrderNotArriveQty(values.stream().mapToInt(item -> item.get().getOrderNotArriveQty()).sum());

           homeSkuTotalDTO.setReplenishNotArriveQty(values.stream().mapToInt(item -> item.get().getReplenishNotArriveQty()).sum());

       }

3.BigDecimal

1.求和

BigDecimal sum = Arrays.stream(bdArray).reduce(BigDecimal.ZERO, (p, q) -> p.add(q));

BigDecimal sum = list.stream().map(Person::getWeight)

                               .reduce(BigDecimal.ZERO, BigDecimal::add);

2.自定义求和

BigDecimal sum = map.values().stream().reduce(BigDecimal.ZERO, Utility::addWeight);

import java.math.BigDecimal;

public class Utility {

public static BigDecimal addWeight(BigDecimal w1, BigDecimal w2) {

return w1.add(w2);

}

}

3.举例

import java.math.BigDecimal;

import java.util.Arrays;

import java.util.List;

public class BigDecimalSumUsingList {

public static void main(String[] args) {

Person p1 = new Person("AAA", new BigDecimal("45.23"));

Person p2 = new Person("BBB", new BigDecimal("55.43"));

Person p3 = new Person("CCC", new BigDecimal("65.21"));

Person p4 = new Person("DDD", new BigDecimal("35.73"));

List<Person> list = Arrays.asList(p1, p2, p3, p4);

BigDecimal sum = list.stream().map(Person::getWeight)

                      .reduce(BigDecimal.ZERO, BigDecimal::add);

System.out.println(sum);


sum = list.stream().map(p -> p.getWeight())

               .reduce(BigDecimal.ZERO, (b1, b2) -> b1.add(b2));

System.out.println(sum);


sum = list.stream().map(Person::getWeight)

               .reduce(BigDecimal.ZERO, Utility::addWeight);

System.out.println(sum);


}

}

BigDecimal求和

BigDecimal sum = products.stream()

               .map(Product::getPrice)

               .reduce(BigDecimal.ZERO, BigDecimal::add);

先相乘再累加:

final BigDecimal mgmtPrmAmt = value.stream()

                           .map(product -> product.getMgmtPrmAmt().multiply(new BigDecimal(product.getSalQty())))

                           .reduce(BigDecimal.ZERO, BigDecimal::add);

4.获取前七天

public static void main(String[] args) {

   List<String> dates = new ArrayList<>();

   final DateTime yesterdayDate = DateUtil.yesterday();

   final String yesterday = DateUtil.formatDate(yesterdayDate);

   dates.add(yesterday);

   for (int i = 1; i < 7; i++) {

       final DateTime dateTime = DateUtil.offsetDay(yesterdayDate, -i);

       dates.add(DateUtil.formatDate(dateTime));

   }

   for (String date : dates) {

       System.out.println(date);

   }

}

5.内存分页

pageBean.setTotalElements(tags.size());

           pageBean.setTotalPages(tags.size() / pageQuery.getSize() + (tags.size() % pageQuery.getSize() == 0 ? 0 : 1));

           pageBean.setSize(pageQuery.getSize());

           pageBean.setNumber(pageQuery.getPage());

           pageBean.setContent(tags.stream().skip((pageQuery.getPage() - 1) * pageQuery.getSize()).limit(pageQuery.getSize()).collect(Collectors.toList()));

           pageBean.setNumberOfElements(CollectionUtils.isNotEmpty(pageBean.getContent()) ? pageBean.getContent().size() : 0L);

6.判断集合为空

CollectionUtils.isNotEmpty({a,b}): true

<dependency>

 <groupId>commons-collections</groupId>

 <artifactId>commons-collections</artifactId>

 <version>3.2.2</version>

</dependency>

7.每一天的 top30

你这个问题有点不明确,不知道是什么数据需要排名,下面我以网站访问量为例,给出一种计算每天 top30 访问量的方法。

假设你有一个这样的数据文件,每一行表示某一天某个网站的访问量:

2022-01-01,website1,100

2022-01-01,website2,200

2022-01-01,website3,300

2022-01-02,website1,150

2022-01-02,website2,250

2022-01-02,website3,350

2022-01-03,website1,180

2022-01-03,website2,280

2022-01-03,website3,380

你可以按照日期进行分组,然后对每一组的数据按照访问量排序,取前 30 就是每一天的 top30 访问量。下面是一段 Java 代码实现这个逻辑:

import java.io.BufferedReader;

import java.io.FileReader;

import java.io.IOException;

import java.text.SimpleDateFormat;

import java.util.ArrayList;

import java.util.Comparator;

import java.util.Date;

import java.util.List;

import java.util.Map;

import java.util.stream.Collectors;


public class Top30ByDay {


   public static class Record {

       private Date date;

       private String website;

       private int visits;


       public Record(Date date, String website, int visits) {

           this.date = date;

           this.website = website;

           this.visits = visits;

       }


       public Date getDate() {

           return date;

       }


       public String getWebsite() {

           return website;

       }


       public int getVisits() {

           return visits;

       }

   }


   public static void main(String[] args) throws IOException {

       // 读取数据文件

       List<Record> records = new ArrayList<>();

       try (BufferedReader reader = new BufferedReader(new FileReader("data.txt"))) {

           String line;

           while ((line = reader.readLine()) != null) {

               String[] fields = line.split(",");

               Date date = new SimpleDateFormat("yyyy-MM-dd").parse(fields[0]);

               String website = fields[1];

               int visits = Integer.parseInt(fields[2]);

               Record record = new Record(date, website, visits);

               records.add(record);

           }

       }


       // 按照日期分组,计算每一天的top30访问量

       Map<Date, List<Record>> groupByDate = records.stream()

               .collect(Collectors.groupingBy(Record::getDate));

       SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");

       for (Map.Entry<Date, List<Record>> entry : groupByDate.entrySet()) {

           Date date = entry.getKey();

           List<Record> recordsByDay = entry.getValue();

           List<Record> top30ByDay = recordsByDay.stream()

                   .sorted(Comparator.comparingInt(Record::getVisits).reversed())

                   .limit(30)

                   .collect(Collectors.toList());

           System.out.println(dateFormat.format(date) + " top 30:");

           for (Record record : top30ByDay) {

               System.out.println(record.getWebsite() + " " + record.getVisits());

           }

           System.out.println();

       }

   }

}

这个代码使用 Java 8 的 Stream API,将数据按照日期分组,然后对每一组的数据按照访问量排序并取前 30,输出每一天的 top30 访问量。在这个例子中,我使用了 Java 的日期处理库java.util.Datejava.text.SimpleDateFormat,你可以根据自己的需求替换成其他日期处理库。

8.并行处理

@Test

public void test15() {

   // 调用 parallelStream 方法即能并行处理

   List<String> names = properties.parallelStream()

       .filter(p -> p.priceLevel < 4)

       .sorted(Comparator.comparingInt(Property::getDistance))

       .map(Property::getName)

       .limit(2)

       .collect(Collectors.toList());

   System.out.println(JSON.toJSONString(names));

}

六.jackson 使用

1.依赖

<dependency>

   <groupId>com.fasterxml.jackson.dataformat</groupId>

   <artifactId>jackson-dataformat-xml</artifactId>

</dependency>

<dependency>

   <groupId>com.fasterxml.jackson.core</groupId>

   <artifactId>jackson-databind</artifactId>

</dependency>

2.json 字符串转对象

/**

* 字符串转对象

*

* @throws Exception

*/

@Test

public void test1() throws Exception {

   ObjectMapper objectMapper = new ObjectMapper();

   String carJson = "{ \"brand\" : \"Mercedes\", \"doors\" : 5 }";

   Car car = objectMapper.readValue(carJson, Car.class);

   System.out.println(objectMapper.writeValueAsString(car));

}

3.对象转 json 字符串

/**

* 对象转字符串

*

* @throws Exception

*/

@Test

public void test2() throws Exception {

 Car car = new Car();

 car.setBrand("宝马");

 car.setDoors(8);

 System.out.println(new ObjectMapper().writeValueAsString(car));

}

4.二进制数组转 json 对象

/**

* 二进制数组转对象

*

* @throws Exception

*/

@Test

public void test3() throws Exception {

 ObjectMapper objectMapper = new ObjectMapper();

 String carJson =

         "{ \"brand\" : \"Mercedes\", \"doors\" : 5 }";

 byte[] bytes = carJson.getBytes("UTF-8");

 Car car = objectMapper.readValue(bytes, Car.class);

 System.out.println(objectMapper.writeValueAsString(car));

}

5.json 字符串转 list 集合

/**

* 字符串转lsit

*

* @throws Exception

*/

@Test

public void test4() throws Exception {

   String jsonArray = "[{\"brand\":\"ford\"}, {\"brand\":\"Fiat\"}]";

   ObjectMapper objectMapper = new ObjectMapper();

   List<Car> cars = objectMapper.readValue(jsonArray, new TypeReference<List<Car>>() {

   });

   System.out.println(objectMapper.writeValueAsString(cars));

}

6.list 转 json 字符串

/**

* list转字符串

*

* @throws Exception

*/

@Test

public void test5() throws Exception {

   List<Car> cars = new ArrayList<>();

   Car car1 = new Car();

   car1.setBrand("宝马");

   car1.setDoors(8);

   cars.add(car1);

   Car car2 = new Car();

   car2.setBrand("奔驰");

   car2.setDoors(10);

   cars.add(car2);

   System.out.println(new ObjectMapper().writeValueAsString(cars));

}

7.json 字符串转 map

/**

* 字符串转map

*

* @throws Exception

*/

@Test

public void test6() throws Exception {

   String jsonObject = "{\"brand\":\"ford\", \"doors\":5}";

   ObjectMapper objectMapper = new ObjectMapper();

   Map<String, Object> jsonMap = objectMapper.readValue(jsonObject,

           new TypeReference<Map<String, Object>>() {

           });

   System.out.println(objectMapper.writeValueAsString(jsonMap));

}

七.函数式接口

1.新接口

以下是一些常用的函数式接口:

  1. Supplier (java.util.function.Supplier<T>):表示一个供应商,它不接受参数,但返回一个值。在函数式编程中,常用于延迟计算或提供初始值。
  2. Function (java.util.function.Function<T, R>):表示一个函数,它接受一个参数类型为 T 的对象,然后返回一个类型为 R 的结果对象。
  3. Predicate (java.util.function.Predicate<T>):表示一个断言,它接受一个参数类型为 T 的对象,返回一个布尔值,用于判断对象是否满足某个条件。
  4. UnaryOperator (java.util.function.UnaryOperator<T>):是一个特殊的 Function,输入和输出类型都是相同的。用于表示只接受一个参数并返回相同类型结果的操作。
  5. BinaryOperator (java.util.function.BinaryOperator<T>):是一个特殊的 Function,输入和输出类型都是相同的。用于表示接受两个参数并返回一个相同类型结果的操作。
  6. BiFunction (java.util.function.BiFunction<T, U, R>):与 Function 类似,但接受两个参数类型分别为 TU 的对象,然后返回一个类型为 R 的结果对象。
  7. Consumer 接口的变种: 除了常规的 Consumer,还有 IntConsumerLongConsumerDoubleConsumer 分别用于处理整数、长整数和双精度浮点数。

这些函数式接口可以通过 Java 8 中的 java.util.function 包来使用,它们在函数式编程和 Lambda 表达式的应用中非常有用,可以让代码更加简洁和易于理解。

2.Consumer

Consumer 可以在函数式编程中的很多场景中使用,例如遍历集合并执行某种操作,执行异步任务的回调等。

是的,除了 Consumer,Java 8 引入了一系列函数式接口,用于支持不同类型的函数式操作。

在 Java 8 中,Consumer 是一个函数式接口,它定义了一个接受一个参数并且不返回任何结果的操作。它在函数式编程中常用于表示一个可以对传入的参数执行某种操作的函数。

Consumer 接口有一个抽象方法 accept(T t),该方法接受一个参数类型为 T 的对象,并对该对象进行操作,但不返回任何结果。

下面是 Consumer 的简单示例:

import java.util.function.Consumer;


public class ConsumerExample {

   public static void main(String[] args) {

       // 使用 Consumer 打印字符串

       Consumer<String> printConsumer = str -> System.out.println(str);

       printConsumer.accept("Hello, world!");


       // 使用 Consumer 修改集合中的元素

       List<String> names = new ArrayList<>();

       names.add("Alice");

       names.add("Bob");

       names.add("Charlie");


       Consumer<List<String>> modifyConsumer = list -> {

           for (int i = 0; i < list.size(); i++) {

               list.set(i, list.get(i).toUpperCase());

           }

       };


       modifyConsumer.accept(names);

       System.out.println(names); // 输出: [ALICE, BOB, CHARLIE]

   }

}

在上面的示例中,我们创建了两个不同的 Consumer 实例,一个用于打印字符串,另一个用于将集合中的元素转换为大写。accept 方法负责执行相应的操作。

相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore &nbsp; &nbsp; ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库&nbsp;ECS 实例和一台目标数据库&nbsp;RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&amp;RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
相关文章
|
16天前
|
安全 Java 大数据
探索Java的奇妙世界:语言特性与实际应用
探索Java的奇妙世界:语言特性与实际应用
|
22天前
|
Java 开发者 微服务
《Java 简易速速上手小册》第10章:Java 未来趋势和新特性(2024 最新版)
《Java 简易速速上手小册》第10章:Java 未来趋势和新特性(2024 最新版)
35 0
|
2天前
|
Java 编译器 开发者
Java一分钟之-继承:复用与扩展类的特性
【5月更文挑战第9天】本文探讨了Java中的继承机制,通过实例展示了如何使用`extends`创建子类继承父类的属性和方法。文章列举了常见问题和易错点,如构造器调用、方法覆盖、访问权限和类型转换,并提供了解决方案。建议深入理解继承原理,谨慎设计类结构,利用抽象类和接口以提高代码复用和扩展性。正确应用继承能构建更清晰、灵活的代码结构,提升面向对象设计能力。
9 0
|
6天前
|
安全 Java 程序员
Java 8新特性之Lambda表达式
【5月更文挑战第5天】 本文将介绍Java 8中的一个重要新特性——Lambda表达式。Lambda表达式是Java 8引入的一种简洁、易读的函数式编程语法,它允许我们将函数作为参数传递给方法,或者作为返回值。通过使用Lambda表达式,我们可以编写更简洁、更易读的代码,提高开发效率。
|
10天前
|
分布式计算 Java API
Java 8新特性之Lambda表达式与Stream API
【5月更文挑战第1天】本文将介绍Java 8中的两个重要特性:Lambda表达式和Stream API。Lambda表达式是一种新的函数式编程语法,可以简化代码并提高可读性。Stream API是一种用于处理集合的新工具,可以方便地进行数据操作和转换。通过结合Lambda表达式和Stream API,我们可以更加简洁高效地编写Java代码。
|
11天前
|
供应链 Java API
Java 8新特性解析及应用区块链技术在供应链管理中的应用与挑战
【4月更文挑战第30天】本文将深入探讨Java 8的新特性,包括Lambda表达式、Stream API和Optional类等。通过对这些新特性的详细解析和应用实例,帮助读者更好地理解和掌握Java 8的新技术。
|
11天前
|
安全 Java API
Java 8新特性概述及其对编程实践的影响
【4月更文挑战第30天】本文将详细讨论Java 8的新特性,包括Lambda表达式、Stream API以及Optional类等,并探讨这些新特性如何改变了Java编程的实践。我们将通过实例代码展示这些新特性的用法,并分析其对提高代码可读性和编写效率的影响。
|
12天前
|
安全 Java API
Java 8新特性深度解析
【4月更文挑战第30天】本文将深入探讨Java 8的新特性,包括Lambda表达式、Stream API、Optional类等,以及这些新特性如何改变我们编写Java代码的方式。
|
12天前
|
分布式计算 Java 大数据
【Java探索之旅】我与Java的初相识(一):Java的特性与优点及其发展史
【Java探索之旅】我与Java的初相识(一):Java的特性与优点及其发展史
22 0
|
12天前
|
Java API
Java 8新特性之Lambda表达式详解
【4月更文挑战第29天】本文将深入探讨Java 8中引入的Lambda表达式,这是Java历史上的一次重大变革。我们将详细解析Lambda表达式的基本概念,语法结构,以及如何在实际编程中应用。此外,我们还将探讨Lambda表达式与函数式接口的关系,以及它如何改变我们编写和理解Java代码的方式。