JAVA:Stream流式编程,解放你的生产力

一、函数式编程

  函数式编程(Functional Programming,简称 FP)是一种编程范式,它强调将计算视为数学函数的评估,避免改变状态以及可变数据。与过程式编程和面向对象编程不同,函数式编程强调函数的纯洁性(即无副作用)和不可变性(即数据一旦创建就不能改变)。

  在 Java 8 中,引入了函数式接口(Functional Interface)的概念,使得函数式编程在 Java 中也能得以实现。

二、函数式接口

  函数式接口(Functional Interface)就是一个有且仅有一个抽象方法,但是可以有多个非抽象方法的接口。 java8引入@FunctionalInterface 注解声明该接口是一个函数式接口。

  函数式接口是Java8支持函数式编程的基础,函数式接口允许开发者使用Lambda表达式来创建其实例。

三、常见的函数接口类型

断言式接口 Predicate<T>:接收 T 对象并返回 boolean。

消费型接口  Consumer<T>:接收 T 对象,不返回值。

函数型接口  Function<T, R>:接收 T 对象,返回 R 对象。

供给型接口  Supplier<T>:提供 T 对象(例如工厂),不接收值。

UnaryOperator<T>:接收 T 对象,返回 T 对象。

BinaryOperator<T>:接收两个 T 对象,返回 T 对象。

四、Lambda表达式

  Lambda表达式是Java 8中引入的一个核心特性,它允许我们以简洁、紧凑的方式表示一个匿名函数。Lambda表达式基于函数式编程的概念,允许我们定义一个接受特定参数并返回结果的函数,而无需为其指定一个名称。

  Lambda表达式可以作为方法的参数使用,这使得代码更加简洁紧凑,并为函数式编程提供了支持。

  Lambda表达式是一个对象,它必须赋给一个函数式接口,这种接口可以通过@FunctionalInterface显式指明,它只能有一个方法。

五、Stream流式编程

  Stream API是Java 8引入的一个新特性,用于处理数据集合(如List、Set等)。它提供了一种声明性、函数式的方式来处理数据,支持过滤、映射、排序、聚合等操作。 以下是一些常用的流程编程操作代码示例:

准备测试数据

public class User {

    private String name;

    private Integer age;

    private String grade;

    private Integer score;

    public User(String name, Integer age, String grade, Integer score) {
        this.name = name;
        this.age = age;
        this.grade = grade;
        this.score = score;
    }

    public String getName() {
        return name;
    }

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

    public Integer getAge() {
        return age;
    }

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

    public String getGrade() {
        return grade;
    }

    public void setGrade(String grade) {
        this.grade = grade;
    }

    public Integer getScore() {
        return score;
    }

    public void setScore(Integer score) {
        this.score = score;
    }

    @Override
    public String toString() {
        return "User{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", grade='" + grade + '\'' +
                ", score=" + score +
                '}';
    }
}
		User user1 = new User("张三", 6, "一年级", 70);
        User user2 = new User("李四", 7, "一年级", 75);
        User user3 = new User("王五", 7, "二年级", 80);
        User user4 = new User("赵六", 8, "三年级", 85);
        User user5 = new User("张飞", 5, "一年级", 90);

        List<User> userList = new ArrayList<>();
        userList.add(user1);
        userList.add(user2);
        userList.add(user3);
        userList.add(user4);
        userList.add(user5);

1. 遍历/匹配(foreach/find/match)

// 遍历输出数据
userList.forEach(user -> System.out.println(user));

// 匹配查找第一个
Optional<User> firstUser = userList.stream().filter(user -> user.getAge() > 6).findFirst();
System.out.println(firstUser.get());

// 随机匹配查找一个,parallelStream(并行流)
Optional<User> anyUser = userList.parallelStream().filter(user -> user.getAge() > 6).findAny();
System.out.println(anyUser.get());

// 是否包含大于8的年龄的学生
boolean anyMatch = userList.stream().anyMatch(user -> user.getAge() > 8);
System.out.println(anyMatch);

2. map/flatMap

将流的元素映射成另一个类型

map:接收一个函数作为参数,该函数会被应用到每个元素上,并将其映射成一个新的元素。

flatMap:接收一个函数作为参数,将流中的每个值都换成另一个流,然后把所有流连接成一个流。

// 获取名称到一个新的列表中
List<String> nameList = userList.stream().map(user -> user.getName()).collect(Collectors.toList());
System.out.println(nameList);

3. filter
对流的元素过滤

// filter  获取年龄=7的学生
List<User> ageList = userList.stream().filter(user -> user.getAge() == 7).collect(Collectors.toList());
System.out.println(ageList);

4. 聚合(max/min/count)

// 年龄最大的学生
Optional<User> maxUser = userList.stream().max(Comparator.comparing(User::getAge));
System.out.println(maxUser.get());

// 年龄大于6的有几个人
long count = userList.stream().filter(user -> user.getAge() > 6).count();
System.out.println(count);

5. sorted

对流的元素排序

// 按照年龄进行 排序
List<User> sortedList = userList.stream().sorted(Comparator.comparing(User::getAge)).collect(Collectors.toList());
System.out.println(sortedList);

// 先按照年龄排序,在按照分数排序,且排序方式使用自定义方式
List<User> sortedList2 = userList.stream().sorted((p1, p2) -> {
	if (p1.getAge() == p2.getAge()) {
		return p2.getScore() - p1.getScore();
	} else {
		return p2.getAge() - p1.getAge();
	}
}).collect(Collectors.toList());
System.out.println("sortedList2==" + JSONObject.toJSONString(sortedList2));

6. distinct

去除流中重复的元素

List<Integer> distinctList = userList.stream().map(User::getAge).distinct().collect(Collectors.toList());
System.out.println(distinctList);

7. reduce

对流中的元素归约操作,将每个元素合起来形成一个新的值

//分数的总合
Integer reduce = userList.stream().map(User::getScore).reduce((x, y) -> x + y).get();
System.out.println(reduce);

8. groupingBy

分组操作

// 按照年级分组
Map<String, List<User>> map1 = userList.stream().collect(Collectors.groupingBy(User::getGrade));
System.out.println("map1=" + JSONObject.toJSONString(map1));

// 按照年龄段分组
Map<Integer, List<User>> map2 = userList.stream().collect(Collectors.groupingBy(user -> {
	if (user.getAge() <= 6) {
		return 1;
	} else if (user.getAge() == 7) {
		return 2;
	} else {
		return 3;
	}
}));
System.out.println("map2=" + JSONObject.toJSONString(map2));

// 多级分组(按照年级分组之后,每个年级再按照年龄分组)
Map<String, Map<Integer, List<User>>> map3 = userList.stream().collect(Collectors.groupingBy(User::getGrade, Collectors.groupingBy(user -> {
	if (user.getAge() <= 6) {
		return 1;
	} else if (user.getAge() == 7) {
		return 2;
	} else {
		return 3;
	}
})));
System.out.println("map3=" + JSONObject.toJSONString(map3));

9. limit/skip

limit():截取流中前面几个元素

skip():跳过流中前面几个元素

// 从第一条数据开始,每2条出来
List<User> userList1 = userList.stream().skip(0).limit(2).collect(Collectors.toList());
System.out.println("userList1=" + JSONObject.toJSONString(userList1));

10. 两个列表取交集/并集

List<Integer> list1 = Arrays.asList(1, 2, 3, 4, 5);

List<Integer> list2 = Arrays.asList(4, 5, 6, 7, 8);
// 交集
List<Integer> list3 = list1.stream()
		.filter(item -> list2.contains(item))
		.collect(Collectors.toList());
System.out.println(list3);

// 并集
List<Integer> list4 = Stream.concat(list1.stream(), list2.stream())
		.distinct()
		.collect(Collectors.toList());
System.out.println(list4);

11. 根据列表中的对象某个属性进行去重

List<User> userList2 = userList.stream().collect(
		collectingAndThen(
				Collectors.toCollection(
						() -> new TreeSet<>(Comparator.comparing(User::getName))), ArrayList::new));

System.out.println("userList2=="+JSONObject.toJSONString(userList2));

以上就是使用stream进行的流式编程,希望对你能有所帮助。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值