【MapSheep】
[好记性不如烂笔头]

Java之Lambda使用

Stream接口中的常见方法

List<Integer> nums =Arrays.asList(1,1,null,2,3,4,null,5,6,7,8,9,10);
System.out.println("sum is:"+nums.stream()
      .filter(num -> num != null)    // 流中:1,1,2,3,4,5,6,7,8,9,10
      .distinct()                    // 流中:1,2,3,4,5,6,7,8,9,10
      .mapToInt(num -> num * 2)      // 流中:2,4,6,8,10,12,14,16,18,20
      .peek(System.out::println)     // 当元素被消费时,打印自身:2,4,6,8,10,12
      .skip(2)         // 流中:6,8,10,12,14,16,18,20
      .limit(4)        // 流中:6,8,10,12
      .sum());         // 总计:36 = 6+8+10+12
 
 
结果:
2
4
6
8
10
12
sum is:36

流操作

1.Java中filter和removeIf.

  1. 介绍
    • 区别:
      • filter过滤, 会把符合的留下来.
      • removeIf过滤之后, 会把相同的干掉.
  2. 示例
List<Student> stuList = new ArrayList<>();
Collections.addAll(stuList,
        new Student(1, "张三"),
        new Student(2, "李四"),
        new Student(3, "王老五")
);

// 使用filter过滤之后(会把符合的留下来,比如:Student{stuId=1, stuName='张三'})
List<Student> filterList = stuList.stream().filter(student -> {
    Integer valueOf = Integer.valueOf("1");
    return !valueOf.equals(student.getStuId());
}).collect(Collectors.toList());

// 使用removeIf过滤之后(会把相同的干掉,比如干掉了“王老五”)
boolean removeIf = filterList.removeIf(student -> {
    Integer valueOf = Integer.valueOf("3");
    return valueOf.equals(student.getStuId());
});

// 最后剩下:Student{stuId=2, stuName='李四'}
filterList.forEach(System.out::println);

// 10. 使用filter保留两个集合的交集, stu02List_新的集合
stuList.stream().filter(stu02List::contains).collect(Collectors.toList());

// 11. 差集
List<User> resultList = createList().stream()
        .filter(o->!newList.contains(o)).collect(Collectors.toList());

2.Java中forEach使用.

  1. 介绍
    • 集合的遍历forEach方法
  2. 示例
    // 1. 输出一列
    list.stream().forEach(v -> System.err.println(v.getName()+","+v.getSex()));

    // 2. 遍历Map集合
    map.forEach((key, value) -> System.out.println("key:" + key + "; value" + JSON.toJSON(value)));

3.Java中Peek使用.

  1. 介绍
    • peek 方法很简单,我们在 peek 方法里面做任意没有返回值的事情,比如打印日志.
    • 与forEach()方法效果类似,但该方法会返回一个新的流,而forEach()无返回
  2. 示例
// 1. 打印日志
public void testPeek() {
    List<String> list = new ArrayList<String>() {{
        add("1");
        add("2");
        add("3");
    }};
    list.stream().map(s -> Integer.valueOf(s))
            .peek(s -> System.out.println(s))
            .collect(Collectors.toList());
}

// 2. 给List集合中某一个字段、数组赋值
wordVoList.stream().peek(aItem - > {
        List<String> strList =  xxxMapper.findAll();
        aItem.setstuList(strList);
    }
).collect(collectors.toList());

// 3. 使用peek调用方法给集合中字段赋值
.stream().peek(xxxServiceImpl::accept).collect(collectors.toList());

private static void accept(ExperienceVO aItem) {
    if (不等于空) {
        aItem.setCaseStatusFlag(ExperienceEnum.getValue(aItem.CaseStatus()));
    }
}

4.Java中Map使用.

  1. 介绍
    • map 方法可以让我们进行一些流的转化,比如原来流中的元素是 A,通过 map 操作,可以使返回的流中的元素是 B.
  2. 实例
// 1. 通过 map 方法list中元素转化成 小写
public void testMap() {
    List<String> list = new ArrayList<String>() {{
        add("1");
        add("2");
        add("3");
    }};
    List<String> strLowerList = list.stream()
            .map(str -> str.toLowerCase())
            .collect(Collectors.toList());
}

// 2. 将集合中某个字段转换为单独一个集合的两种方式.
List<Integer> listPlus =  list.stream().map(value -> value.getId()).collect(Collectors.toList()); 
List<Integer> listPlus =  list.stream().map(Student::getId).collect(Collectors.toList());

// 3. 将DTO转换为VO
private static List<LocationVo> convert2LocationVo(List<LocationDto> locationDtoList) {
    if (null == locationDtoList) {
        return null;
    }
    return locationDtoList.stream().map(item -> {
        LocationVo locationVo = new LocationVo();
        locationVo.setUpdateBy(item.getUpdateBy());
        locationVo.setUpdateDate(item.getUpdateDate());
        locationVo.setVersion(item.getVersion());
        return locationVo;
    }).collect(Collectors.toList());
}

// 4. Lambda .map this调用方法
//聚合方法
private List<StudentPlus> obj(List<Student> stuList) {
    return stuList.stream().map(this::conversion).collect(Collectors.toList());
}

//转换方法
private StudentPlus conversion(Student stu) {
    StudentPlus studentPlus = new StudentPlus();
    studentPlus.setId(stu.getId());
    studentPlus.setName(stu.getName());
    studentPlus.setDate(new Date(stu.getDate()));
    return studentPlus;
}

// 5.List<>转List<map<,>>
List<Map<String,Object>> personToMap = peopleList.stream().map((p) -> {
    Map<String, Object> map = new HashMap<>();
    map.put("is", p.getId());
    map.put("age", p.getAge());
    return map;
}).collect(Collectors.toList());

5.Java中MapTo...使用.

  1. 介绍
    • mapToInt 方法的功能和 map 方法一样,只不过 mapToInt 返回的结果已经没有泛型,已经明确是 int 类型的流了,源码如下:
  2. 实例
public void testMapToInt () {
    List<String> list = new ArrayList<String>() {{
        add("1");
        add("2");
        add("3");
    }};
    List<Integer> collect = list.stream()
            .mapToInt(s -> Integer.valueOf(s))
            // 一定要有 mapToObj,因为 mapToInt 返回的是 IntStream,因为已经确定是 int 类型了
            // 所有没有泛型的,而 Collectors.toList() 强制要求有泛型的流,所以需要使用 mapToObj
            // 方法返回有泛型的流
            .mapToObj(s -> s)
            .collect(Collectors.toList());
    double sum = list.stream()
            .mapToDouble(s -> Double.valueOf(s))
            // DoubleStream/IntStream 有许多 sum(求和)、min(求最小值)、max(求最大值)、average(求平均值)等方法
            .sum();

}

6.Java中Distinct使用.

  1. 介绍
    • distinct 方法有去重的功能
    • 可在.map()、.stream()关键字之后使用.
  2. 实例
public void testDistinct(){
    List<String> list = new ArrayList<String>() {{
        add("1");
        add("2");
        add("2");
    }};
    list.stream()
            .map(s -> Integer.valueOf(s))
            .distinct()
            .collect(Collectors.toList());
}

7.Java中Sorted使用.

  1. 介绍
    • Sorted 方法提供了排序的功能,并且允许我们自定义排序
  2. 实例
public void testSorted() {
    List<String> list = new ArrayList<String>() {{
        add("1");
        add("2");
        add("3");
    }};
    list.stream()
            .map(s -> Integer.valueOf(s))
            // 等同于 .sorted(Comparator.naturalOrder()) 自然排序
            .sorted()
            .collect(Collectors.toList());
    // 自定义排序器
    list.stream()
            .map(s -> Integer.valueOf(s))
            // 反自然排序
            .sorted(Comparator.reverseOrder())
            .collect(Collectors.toList());
}

// 2. 降序
.sorted(Comparator.comparing(ResourceFeverRankingVO::getDateSoft).reversed())
.collect(Collectors.toList());

// 3. 升序
studentList.stream().sorted(Comparator.comparing(StudentInfo::getAge)).collect(Collectors.toList())

8.Java中skip使用.

  1. 介绍
    • 跳过流中前面几个元素, 下标从0开始
  2. 实例
List<String> list = new ArrayList<>();
Collections.addAll(list, "张三", "李四", "王老五", "潘丽平");
System.out.println(list.stream().skip(2).collect(Collectors.toList()));
// TODO 输出: [王老五, 潘丽平]

9.Java中flatMap使用.

  1. 介绍
    • Lambda中Map是对流元素进行转换,flatMap 是对流中的元素(集合)进行平铺后合并,即对流中的每个元素平铺后又转换成为了 Stream 流。
    • flatMap 首先将一个函数应用于元素,然后将其展平,当你需要将 [[a,b,c],[d,e,f],[x,y,z]] 具有两个级别的数据结构转换为 [a,b,c,d,e,f,x,y,z] 这样单层的数据结构时,就选择使用 flatMap 处理。
    • 如果是 [a,b,c,d,e,f,x,y,z] 转换为大写 [A,B,C,D,E,F,X,Y,Z] 这样单层转换,就使用 map 即可。
  2. 示例
// 1.将一个字符串列表分割成单个字符列表:
// 输出 ["hello", "world"]转换为["h","e","l","l","o","w","o","r","l","d"]
List<String> dataList = Lists.newArrayList("hello", "world");
List<String> transform = dataList.stream()
    .flatMap(
      data -> Arrays.stream(data.split(""))
    )
    .collect(Collectors.toList());
System.out.println(JSON.toJSONString(transform));

// 2.将一个二维数组转换为一个一维数组:
int[][] array = {{1, 2}, {3, 4}, {5, 6}};
int[] flatArray = Arrays.stream(array)
        .flatMapToInt(Arrays::stream)
        .toArray();
System.out.println(Arrays.toString(flatArray)); // 输出 [1, 2, 3, 4, 5, 6]

// 3.将一个对象列表中的属性转换为一个列表
class Person {
    private String name;
    private List<String> hobbies;

    // 省略构造函数和 getter/setter 方法
}

List<Person> personList = Arrays.asList(
        new Person("Alice", Arrays.asList("reading", "swimming")),
        new Person("Bob", Arrays.asList("hiking", "cooking"))
);
List<String> hobbyList = personList.stream()
        .flatMap(person -> person.getHobbies().stream())
        .collect(Collectors.toList());
System.out.println(hobbyList); // 输出 ["reading", "swimming", "hiking", "cooking"]

// 4. .map和.flatMap关键字配合使用
List<Person> people = Arrays.asList(
                            new Person("John", 30),
                            new Person("Jane", 25),
                            new Person("Bob", 40)
                        );
List<Integer> ages = people.stream()
                            .filter(person -> person.getAge() > 30)
                            .map(Person::getAge)
                            .flatMap(age -> Stream.of(age))
                            .collect(Collectors.toList());
// 输出 [40]

10.Java中FindFirst、findAny 查找使用.

  1. 介绍
    • findAny查找前流中的任意元素
    • findFirst查找第一个元素
  2. 实例

public class Menu {
	
	/**
	 * 菜品名称
	 */
	private String name;
	/**
	 * 菜品单价
	 */
	private Double price;
	/**
	 * 菜品斤数
	 */
	private Double kilo;
	/**
	 * 菜品类型:蔬菜、水果、肉类
	 */
	private String type;
}

Menu pork    = new Menu("猪肉", 9.9, 10.0, "肉类");
Menu beef    = new Menu("牛肉", 38.8, 5.0, "肉类");
Menu chicken = new Menu("鸡肉", 6.5, 30.0, "肉类");
Menu tomato  = new Menu("土豆", 3.5, 30.0, "蔬菜");
Menu potato  = new Menu("西红柿", 7.5, 20.0, "蔬菜");
Menu apple   = new Menu("苹果", 3.5, 20.0, "水果");
Menu orange  = new Menu("橙子", 4.0, 20.0, "水果");
List<Menu> menuList = Arrays.asList(pork, beef, chicken, tomato, potato, apple, orange);

// 苹果
menuList.stream().filter(menu -> menu.getType().equals("水果")).findFirst().ifPresent(menu -> System.out.println(menu.getName()));

// 苹果 (findAny查找前流中的任意元素)
Optional<Menu> fruitMenu = menuList.stream().filter(menu -> menu.getType().equals("水果")).findAny();

// 示例2 (findFirst查找第一个元素)
Optional<Menu> fruitMenu = menuList.stream().filter(menu -> menu.getType().equals("水果")).findFirst();
if (fruitMenu != null && fruitMenu.isPresent() && fruitMenu.get().getName() != null) {
    System.out.println(fruitMenu.get().getName() +"--"+fruitMenu.get().getPrice());
}
// 输出 苹果--3.5


11.Java中Limit使用.

  1. 介绍
    • limit 方法会限制输出值个数,入参是限制的个数大小
  2. 实例
public void testLimit(){
    List<String> list = new ArrayList<String>() {{
        add("1");
        add("2");
        add("3");
    }};
    list.stream()
            .map(s -> Integer.valueOf(s))
            .limit(2L)
            .collect(Collectors.toList());
}

12.Java中Max,Min使用.

  1. 介绍
    • 通过max、min方法,可以获取集合中最大、最小的对象
  2. 实例
public void testMaxMin(){
    List<String> list = new ArrayList<String>() {{
        add("1");
        add("2");
        add("2");
    }};
    list.stream().max(Comparator.comparing(s -> Integer.valueOf(s))).get();
    list.stream().min(Comparator.comparing(s -> Integer.valueOf(s))).get();
}

13.Java中 匹配 anyMatch allMatch noneMatch使用.

  1. 介绍

  2. 示例

// 1.anyMatch检查谓词是否至少匹配一个元素
// 输出 true
boolean isVegetables = menuList.stream().anyMatch(menu -> menu.getType().equals("蔬菜"));
System.out.println(isVegetables);

// 2.allMatch检查谓词是否匹配所有元素
// 输出 false
boolean isAllVegetables = menuList.stream().allMatch(menu -> menu.getType().equals("蔬菜"));
System.out.println(isAllVegetables);

// 3.noneMatch确保流中没有任何元素与给定的谓词匹配
// 输出 true
boolean isNoneDrink = menuList.stream().noneMatch(menu -> menu.getType().equals("酒水"));
System.out.println(isNoneAllVegetables);

14.Java中归约 reduce使用.

  1. 介绍
    • 归约:将流归约成一个值。
    • 就像相加
  2. 示例
// 输出 73.69999999999999
double totalPrice = menuList.stream().map(Menu::getPrice).reduce(0.0, (a, b) -> a + b);
System.out.println(totalPrice);

// 保留一位小数 73.7
double totalPrice = menuList.stream().map(menu -> {return new BigDecimal(menu.getPrice());}).reduce(BigDecimal.ZERO, BigDecimal::add).doubleValue();
System.out.println(totalPrice);

// 归约查找最大值(找到最大值)
double maxPrice = menuList.stream().map(Menu::getPrice).reduce(Double::max).get();
System.out.println(maxPrice);

15.Java中 数值范围 range rangeClosed使用.

  1. 介绍
  2. 示例
// 1.rangeClosed 第一个参数接受起始值,第二个参数接受结束值。rangeClosed包含结束值。
IntStream is = IntStream.rangeClosed(1, 100).filter(i -> i % 2 == 0);
is.forEach(System.out::println);
// 输出 2 4 6 8 ...... 96 98 100

// 2.range 第一个参数接受起始值,第二个参数接受结束值。range是不包含结束值的
LongStream ls = LongStream.range(1, 100);
ls.forEach(System.out::println);
// 输出 1 2 3 4 ...... 97 98 99


16.Java中 值创建流使用.

  1. 介绍
  2. 示例
Stream<String> ss = Stream.of("ilob", "beh", "jb");
ss.map(String::toUpperCase).forEach(System.out::println);
// 输出 ILOB BEH JB

17.Java中 数值流 mapToDouble、mapToLong、mapToInt使用.

  1. 介绍
  2. 示例
// 1.mapToDouble
// 输出 73.69999999999999
double sum = menuList.stream().mapToDouble(Menu::getPrice).sum();
System.out.println(sum);

// 2.保留1位小数
// 输出 73.7
DecimalFormat df = new DecimalFormat();
df.setRoundingMode(RoundingMode.HALF_UP);
 
double sum = menuList.stream().mapToDouble(Menu::getPrice).sum();
System.out.println(df.format(sum));

// 3. mapToLong
// 输出 10
List<Long> longList = Arrays.asList(1L, 2L, 3L, 4L);
long longsum = longList.stream().mapToLong(Long::longValue).sum();
System.out.println(longsum);

// 4. mapToInt
// 输出 Sum of length: 21
List<String> list = Arrays.asList("apple", "banana", "orange", "kiwi");
int sum = list.stream().mapToInt(str -> str.length()).sum();
System.out.println("Sum of length: " + sum);

18.Java中 收集器使用.

  1. 介绍
  2. 示例
// 1.Collectors.counting() 统计流中元素的数量并返回计数结果
// 输出 7 7
long count = menuList.stream().count();
System.out.println(count);
System.out.println(menuList.stream().collect(Collectors.counting()));

// 2.Collectors.maxBy()
// 输出 38.8
double max = menuList.stream().collect(Collectors.maxBy(Comparator.comparing(Menu::getPrice))).get().getPrice();
System.out.println(max);

// 3.Collectors.minBy()
// 输出 3.5
double min = menuList.stream().collect(Collectors.minBy(Comparator.comparing(Menu::getPrice))).get().getPrice();
System.out.println(min);

// 4.Collectors.summingDouble() 计算流中元素的总和并返回总和结果
// 输出 135.0
double sum = menuList.stream().collect(Collectors.summingDouble(Menu::getKilo));
System.out.println(sum);

// 5.Collectors.averagingDouble() 计算流中元素的平均值并返回平均值结果
// 输出 19.29
DecimalFormat df = new DecimalFormat("#.00");
df.setRoundingMode(RoundingMode.HALF_UP);
double avg = menuList.stream().collect(Collectors.averagingDouble(Menu::getKilo));
System.out.println(df.format(avg));

// 6. Collectors.summarizingDouble() 计算流中元素的统计信息并返回一个DoubleSummaryStatistics对象,该对象包含了求和、平均值、计数、最大值和最小值等信息。
// 输出 DoubleSummaryStatistics{count=7, sum=73.700000, min=3.500000, average=10.528571, max=38.800000}
DoubleSummaryStatistics dss = menuList.stream().collect(Collectors.summarizingDouble(Menu::getPrice));
System.out.println(dss);

19.Java中Collectors.joining使用.

  1. 介绍
    • 自定义连接字符串
  2. 实例

    请点击





非流操作

1.Java中groupingBy使用.

  1. 介绍
    • groupingBy 是能够根据字段进行分组
      • toMap 是把 List 的数据格式转化成 Map 的格式
  2. 实例
// 1. 自定义分组
public void testGroupBy(){
    List<String> list = new ArrayList<String>() {{
        add("1");
        add("2");
        add("2");
    }};
    Map<String, List<String>> strList = list.stream().collect(Collectors.groupingBy(s -> {
        if("2".equals(s)) {
            return "2";
        }else {
            return "1";
        }
    }));
}

// 2. 按类目进行分组
Map<String, List<Product>> prodMap= prodList.stream().collect(Collectors.groupingBy(Product::getCategory));

// 3. 先按照类别分组,再聚合求总数
prodList.stream()
            .collect(Collectors.groupingBy(Product::getCategory, Collectors.counting()));

// 4. 先按照类别分组,再聚合运算(把num相加)
prodList.stream()
            .collect(Collectors.groupingBy(Product::getCategory, Collectors.summingInt(Product::getNum)));

2.Java中Collect使用.

  1. 介绍
    • 将操作后的对象转化为新的对象
  2. 实例
// 1.转换为List集合
list.stream().map(s -> Integer.valueOf(s)).collect(Collectors.toList());

// 2.可配合分组使用

// 3.转换为Map的2种方法
.collect(Collectors.toMap(String::valueOf, Function.identity()));
.collect(Collectors.toMap(PersonDto::getId, o -> o));

// 4.List转Map,id作为key,name作为value,id不可重复
Map<Long, String> collect = objects.stream().collect(Collectors.toMap(PersonDto::getId, PersonDto::getUserName));

// 5.List转Map,id作为key,name作为value,如果Id重复取第一个name
Map<Long, String> collect = objects.stream().collect(Collectors.toMap(PersonDto::getId, PersonDto::getUserName, (o1, o2) -> o1));
// 相反 如果Id重复取最后一个name
Map<Long, String> collect2 = objects.stream().collect(Collectors.toMap(PersonDto::getId, PersonDto::getUserName, (o1, o2) -> o2));
posted on 2023-04-19 17:52  (Play)  阅读(248)  评论(0编辑  收藏  举报