JavaAPI(lambda表达式、流式编程)

Lambda表达式

public class LambdaDemo01 {

public static void main(String[] args) {

// InterA x = (int a, int b) -> {

// return a + b;

// };

//继续简化:

// InterA x = (a,b) -> {

// return a + b;

// };

//继续简化

InterA x = (a,b) -> a + b;//lambda表达式

int result = x.sum(10, 20);

System.out.println(result);

}

}
@FunctionalInterface //函数式接口

interface InterA{

int sum(int a, int b);

}

Lambda基础语法

  • (parameters) -> expression //(参数)->表达式

  • (parameters) -> { statements;} //(参数)->{代码块}


    注意:

  • 箭头(->)将参数与Lambda主体分隔开来

  • 参数部分:

  1. 参数可以是任意合法的Java参数列表,可以为空或包含一个或多个参数。

  2. 参数列表的类型名可以省略。 (全部省略或者全部不省略)

  3. 如果参数列表中,参数的数量有且只有一个,则小括号可以省略。

  • Lambda主体:
  1. Lambda主体可以是一个表达式,表达式外的大括号,可加可不加。 没有大括号时,return关键字必须省略。

  2. 也可以是一个代码块。将按照常规的Java语法执行,并且您可能需要使用return语句来返回值。

Lambda表达式的应用:

第一种: 没有参数没有返回值的lambda表达式

interface NoParameterNoReturn {

void print();

}

主函数:

NoParameterNoReturn i1 = () -> {

int a = 10;

int b = 20;

System.out.println("没有参数没有返回值的lambda表达式" + (a + b));

};

i1.print();


第二种: 没有参数但是有返回值

interface NoParameterReturn {

int print();

}

主函数:

NoParameterReturn i2 = () -> {int a = 100; int b = 200; return a + b;};

NoParameterReturn i2 = () -> 100 + 200;

int r1 = i2.print();

System.out.println("r1:"+r1);


第三种:一个参数没有返回值

interface oneParameterNoReturn {

void print(int a);

}

主函数:

oneParameterNoReturn i3 = a -> { int b = a * 10; int c = b +2;

System.out.println(c);};

i3.print(200);


第四种:一个参数有返回值

interface oneParameterReturn {

int print(int a);

}

主函数:

oneParameterReturn i4 = x -> x*10+2;

int r2 = i4.print(200);

System.out.println(r2);


第五种:多个参数没有返回值

interface multiParameterNoReturn {

void print(int a, int b);

}

主函数:

multiParameterNoReturn i5 = (x,y) -> System.out.println("两个参数的乘积:"+x*y);

i5.print(100,200);


第六种: 多个参数有返回值

interface multiParameterReturn {

int print(int a, int b);

}

主函数:

multiParameterReturn i6 = (m,n) -> m*n;

System.out.println("3和5的乘积:"+i6.print(3,5));

Lambda在集合中的应用

  • forEach
  • removerlf

list迭代:

//创建一个集合,存储一堆姓名

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

names.add("tom");

names.add("jack");

names.add("james");

names.add("jane");

names.add("lucy");

names.add("lily");


names.forEach(m-> System.out.println(m));

可以写成:

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

解释:

:: 双冒号表示引用,前面的部分可能是类名或者是实例名,后面就是表示要引用他们的方法,注意引用的方法不能带括号

这样写,相当于将类或者对象的方法逻辑,传入给了函数式接口的抽象方法,作为抽象方法的逻辑。


Set迭代 :

Set<String> emps = new HashSet<>();

emps.add("tom");

emps.add("jack");

emps.add("james");

emps.add("jane");

emps.add("lucy");

emps.add("lily");

// emps.forEach(e->System.out.println(e));

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


Map迭代 :

Map<String,String> maps = new HashMap<>();

maps.put("1","jack");

maps.put("2","jane");

maps.put("3","lucy");

maps.put("4","lily");

maps.forEach((k,v)-> System.out.println(Integer.parseInt(k)*10+","+v));//将key字符串类型转换成整数类型,并将key值乘10,加","拼接valuse值

removeIf按照条件移除元素:

emps.removeIf(m->m.equals("xiaowang"));//如果有xiaowang就移除

System.out.println(emps);

变量的捕获

匿名内部类的变量捕获

在Java中,匿名内部类可以捕获外部变量,即在匿名内部类中引用并访问外部作用域的变量。这种行为称为变量捕获(Variable Capturing)。

  • 实例变量(Instance Variables):如果匿名内部类位于一个实例方法中,它可以捕获并访问该实例的实例变量。

  • 静态变量(Static Variables):匿名内部类可以捕获并访问包含它的类的静态变量。

  • 方法参数(Method Parameters):匿名内部类可以捕获并访问包含它的方法的参数。

  • 本地变量(Local Variables):匿名内部类可以捕获并访问声明为final的本地变量。从Java 8开始,final关键字可以省略,但该变量实际上必须是最终的(即不可修改)。

package com;

public class OuterClass {

private int instanceVariable = 10;

private static int staticVariable = 20;

public void method(String name) {

final int localVar = 30; // Java 8+ 以后,final可以省略

PrintInter pi = new PrintInter() {
@Override
public void print() {
System.out.println("Instance variable: " + instanceVariable);
System.out.println("Static variable: " + staticVariable);
System.out.println("method variable: " + name);
System.out.println("Local variable: " + localVar);
}
};

pi.print();
}

public static void main(String[] args) {

OuterClass obj = new OuterClass();

obj.method("老黑");

}

}

interface PrintInter{

void print();

}

Lambda表达式的变量捕获

在Lambda表达式中,同样可以捕获外部作用域的变量。Lambda表达式可以捕获以下类型的变量:

  • 实例变量(Instance Variables):Lambda表达式可以捕获并访问包含它的实例的实例变量。

  • 静态变量(Static Variables):Lambda表达式可以捕获并访问包含它的类的静态变量。

  • 方法参数(Method Parameters):Lambda表达式可以捕获并访问包含它的方法的参数。

  • 本地变量(Local Variables):Lambda表达式可以捕获并访问声明为final的本地变量。从Java 8开始,final关键字可以省略,但该变量实际上必须是最终的(即不可修改)

public class LambdaVariableCapture {

private int instanceVariable = 10;

private static int staticVariable = 20;

public void method(String name) {

int localVar = 30;

// Lambda表达式捕获外部变量

PrintInter pi = () -> {
@Override
public void print() {
System.out.println("Instance variable: " + instanceVariable);
System.out.println("Static variable: " + staticVariable);
System.out.println("method variable: " + name);
System.out.println("Local variable: " + localVar);
}
};

pi.print();

}

}

interface PrintInter{

void print();

}

集合的流式编程

如果想要进行集合的流式编程,必须使用集合实例调用其stream方法

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

Stream<Integer> stream = numbers.stream();

1.获取每个元素的长度

List<String> names = Arrays.asList("Alice", "Bob", "Charlie");

List<Integer> nameLengths = names.stream() .map(name -> name.length())
.collect(Collectors.toList());

System.out.println(nameLengths); //[5, 3, 7]

2.筛选和过滤集合元素

List<String> names = Arrays.asList("Alice", "Bob", "Charlie");

List<String> filteredNames = names.stream().filter(name -> name.startsWith("A"))
.collect(Collectors.toList());


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

List<Integer> evenNumbers = numbers.stream().filter(number -> number % 2 == 0)
.collect(Collectors.toList());


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

map.put("Alice", 25);

map.put("Bob", 30);

map.put("Charlie", 35);

Map<String, Integer> filteredMap = map.entrySet().stream().filter(entry -> entry.getValue() > 30).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));

3.集合排序

List<Integer> numbers = Arrays.asList(5, 2, 8, 1, 6, 3, 9, 4, 7, 10);

List<Integer> sortedNumbers = numbers.stream().sorted().collect(Collectors.toList());

4.重写映射Map

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

map.put("Alice", 25);

map.put("Bob", 30);

map.put("Charlie", 35);

Map<String, String> mappedMap = map.entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, entry -> "Age: " + entry.getValue()));

5.对Map的键或值进行归约操作

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

map.put("Alice", 25);

map.put("Bob", 30);

map.put("Charlie", 35);

int sumOfValues = map.values().stream().reduce(0, (a, b) -> a + b);

//reduce方法是对流中的元素进行聚合处理,接收两个参数。

//0是初始的累加值 (a, b) -> a + b表示将流中的两个值合并在一起。在这里,a和b 分别代表当前累加值和流中的下一个值,a+b意味着将它们相加。

//最后的值是25+30+35=90

String concatenatedKeys = map.keySet().stream().reduce("", (a, b) -> a + b);

//""初始值 表示一个空字符串,将用于连接所有的键

//a是累计的字符串 b是流中的下一个键。

//结果是"AliceBobCharlie"

Lambda表达式的优缺点

  • 优点:

1.简洁性:Lambda表达式提供了一种更简洁、更紧凑的语法,可以减少冗余的代码和样板代码,使代码更易于理解和维护。

2.代码可读性:Lambda表达式使得代码更加自解释和易读,可以直接将逻辑集中在一起,提高代码的可读性和可维护性。

3.便于并行处理:Lambda表达式与Java 8引入的Stream API结合使用,可以方便地进行集合的并行处理,充分发挥多核处理器的优势,提高代码的执行效率。

4.避免匿名内部类的繁琐语法:相比于使用匿名内部类,Lambda表达式的语法更为简洁,减少了冗余的代码,提高了编码效率。

  • 缺点:

1.只能用于函数式接口:Lambda表达式只能用于函数式接口(只有一个抽象方法的接口),这限制了它的使用范围。如果需要使用非函数式接口,仍然需要使用传统的方式,如匿名内部类。

2.可读性的折衷:尽管Lambda表达式可以提高代码的可读性,但在某些复杂的情况下,Lambda表达式可能变得难以理解和阅读,特别是当表达式变得过于复杂时。

3.变量捕获的限制:Lambda表达式对捕获的变量有一些限制。它们只能引用final或实际上的最终变量,这可能对某些情况下的代码编写和调试带来一些困扰。

4.学习曲线:对于习惯于传统Java编程风格的开发者来说,Lambda表达式是一项新的概念,需要一定的学习和适应过程。

集合的流式编程

简介

Stream编程的简介

Stream是JDK1.8之后出现的新特性,也是JDK1.8新特性中最值得学习的两种新特性之一。(另外一个是 lambda表达式)。

Stream是对集合操作的增强,流不是集合的元素,不是一种数据结构,不负责数据的存储的,并且和IO流没有任何关系。

流更像是 一个迭代器,可以单向的遍历一个集合中的每一个元素,并且不可循环。

为什么要使用集合的流式编程

有些时候,对集合中的元素进行操作的时候,需要使用到其他操作的结果。

在这个过程中,集合的流式编程可以大幅度的简化代码的数量。

将数据源中的数据,读取到一个流中,可以对这个流中的数据进行操作(删除、过滤、映射...)。每次的操作结果也是一个流对象,可以对这个流再进行其他的操作。

使用流式编程的步骤

  1. 获取数据源,将数据源中的数据读取到流中。

  2. 对流中的数据进行各种各样的处理。

  3. 对流中的数据进行整合处理。

过程2中,有若干方法,可以对流中的数据进行各种各样的操作,并且返回流对象本身,这样的操作,被称为中间操作

过程3中,有若干方法,可以对流中的数据进行各种处理并关闭流,这样的操作,被称为最终操作。

在中间操作和最终操作中,基本上所有的方法参数都是函数式接口,可以使用lambda表达式来实现。 使用集合的流式编程,来简化代码量,但是需要对 lambda 表达式做到熟练掌握。

数据源的获取

数据源,既是流中的数据的来源。

是集合的流式编程的第一步,将数据源中的数据读取到流中,进行处理。

注意:将数据读取到流中进行处理的时候,与数据源中的数据没有关系。也就是说,中间操作对流中的数据进行处理、过滤、映射、排序... ,此时是不会影响数据源中的数据的。

// 1、通过Collection接口中的stream()方法获取数据源为Collection的流

Stream<Integer> stream = list.stream();

// 2、通过Collection接口的parallelStream()方法获取数据源为Collection的流

Stream<Integer> stream = list.parallelStream();

// 3、通过Arrays工具类中的stream()方法获取数据源为数组的流

IntStream stream = Arrays.stream(array);

关于 stream() 和 parallelStream:

他们都是Collection集合获取数据源的方法,不同点在于stream()方法获取的数据源是串行的,

parallelStream()获取的数据源是并行的。 parallelStream()内部集成了多个线程对流中的数据进行 操作,效率更高。


第一步:获取数据源,其实就是通过要操作的集合来获取流对象

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

nums.add(1);

nums.add(2);

nums.add(3);

nums.add(4);

nums.add(5);

nums.add(6);

nums.add(7);

nums.add(8);

// parallelStream(): 是并行运算,即多线程

//Stream<Integer> integerStream = nums.parallelStream();

// 串行运算,单线程

Stream<Integer> stream = nums.stream();

最终操作

将流中的数据整合到一起,可以存入一个集合,也可以直接对流中的数据进行遍历、数据统计... ,通过最终操作,需要掌握如何从流中提取出来我们想要的信息

注意事项:最终操作,之所以叫最终操作,是因为,在最终操作执行结束后,会关闭这个流,流中的所有数据都会销毁。如果使用一个已经关闭了的流,会出现异常。

collect

将流中的数据收集到一起,对这些数据进行一些处理。

最常见的处理,就是将流中的数据存入一个集合。

collect方法的参数,是一个Collector接口,而且这个接口并不是一个函数式接口。实现这个接口, 可以自定义收集的规则。但是,绝大部分情况下,不需要自定义,直接使用Collectors工具类提供的方法即可

// 1、转成 List

List<Integer> result1 = list.stream().collect(Collectors.toList());

System.out.println(result1);

// 2、转成 Set

Set<Integer> result2 = list.stream().collect(Collectors.toSet());

System.out.println(result2);

// 3、转成 Map,提供两个函数式接口的实现,分别实现键的生成规则和值的生成规则

Map<Integer, Integer> result3 = list.stream().collect(Collectors.toMap(ele ->ele / 10, ele -> ele));

System.out.println(result3);

reduce

将流中的数据按照一定的规则聚合起来。

两个形参, m,n第一次分别接受第一个和第二个元素, 然后m作为结果并返回,

我们的自定义逻辑是m+n, 因此相当于 m = m +n,

之后的每一个元素都分别赋值给n,m再次当成参数传入。

// 将流的元素,逐一带入到这个方法中,进行运算

// 最终的运算结果,得到的其实是一个 Optional 类型,需要使用get() 获取到里面的数据

int result4 = list.stream().reduce((e1, e2) -> e1 + e2).get();

System.out.println(result4);

count

统计流中的元素数量。

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

System.out.println(result5);

forEach

迭代、遍历流中的数据

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

max & min

获取流中的最大的元素、最小的元素。

// 获取最大值

Integer result6 = list.stream().max(Integer::compareTo).get();

System.out.println("max is : " + result6);

// 获取最小值

Integer result7 = list.stream().min(Integer::compareTo).get();

System.out.println("min is : " + result7);

Matching

allMatch: 只有当流中所有的元素,都匹配指定的规则,才会返回 true

anyMatch: 只要流中有任意的数据,满足指定的规则,都会返回 true

noneMatch: 只有当流中的所有的元素,都不满足指定的规则,才会返回true

// 判断流中是否所有的元素都大于 50

boolean result8 = list.stream().allMatch(ele -> ele > 50);

System.out.println(result8);

// 判断流中是否有大于 50 的数据

boolean result9 = list.stream().anyMatch(ele -> ele > 50);

System.out.println(result9);

// 判断流中是否没有奇数

boolean result10 = list.stream().noneMatch(ele -> ele % 2 != 0);

System.out.println(result10);

find

findFirst: 从流中获取一个元素(一般情况下,是获取的开头的元素)

findAny: 从流中获取一个元素(一般情况下,是获取的开头的元素)

这两个方法,绝大部分情况下,是完全相同的,但是在多线程的环境下, findAny和find返回的结果可能不一样。

Integer result11 = list.parallelStream().findFirst().get();

System.out.println(result11);

Integer result12 = list.parallelStream().findAny().get();

System.out.println(result12);

最终操作的注意事项

最终操作,会关闭流。如果一个流被关闭了,再去使用这个流,就出出现异常。

// 最终操作错误示范

Stream<Integer> stream = list.stream();

long count = stream.count();

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


Exception in thread "main" java.lang.IllegalStateException: stream has already

been operated upon or closed

at

java.util.stream.AbstractPipeline.sourceStageSpliterator(AbstractPipeline.java

:279)

at

java.util.stream.ReferencePipeline$Head.forEach(ReferencePipeline.java:580)

at com.qf.cstream.FinalOperationDemo.main(FinalOperationDemo.java:78)

中间操作

这里先介绍个JUnit测试类:

@Test:该注解有mian方法的功能,能启动JVM虚拟机来运行代码片段

该注解只能放在非静态方法上面。JVM运行的是该注解下面的方法

需要导入两个jar包:

1.和src平级的关系,创建一个文件夹lib

2.放入这两个jar包

  1. 全选两个jar包文件,右键点击。选择 add as library
    @Before:也是放在某一个非静态方法上,该注解所在的方法会先于@Test注解所在的方法之前运行。

@Before

public void pre(){

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

nums.add(1);

nums.add(2);

nums.add(3);

nums.add(4);

nums.add(5);

nums.add(3);

nums.add(4);

nums.add(6);

stream = nums.stream();

}

filter

用来过滤符合某些条件的元素。

@Test

public void testFilter(){

List<Integer> result = stream.filter(e -> e % 2 == 0).collect(Collectors.toList());

System.out.println(result);

}

distinct

去掉流中的重复操作

@Test

public void testDistinct(){

List<Integer> collect = stream.distinct().collect(Collectors.toList());

System.out.println(collect);

}

sorted

排序

sorted: 排序

sorted(): 默认升序排序

sorted(...) 降序要比较器

@Test

public void testSort(){

//默认升序排序

// stream.sorted().forEach(System.out::println);

stream.sorted((a,b)->b-a).forEach(System.out::println);

}

limit

获取前n个元素

@Test

public void testLimit(){

stream.limit(2).forEach(System.out::println);

}

skip

跳过n个元素

@Test

public void testSkip(){

stream.skip(2).forEach(System.out::println);

}

map

映射 想要将每一个元素映射成另外一个样子。

@Test

public void testMap(){

List<String> collect = stream.map(e -> e + "0000").collect(Collectors.toList());

System.out.println(collect);

}

flatMap

压平并映射,即可以将二维的数组或者集合转成一维的数组或者集合。

@Test

public void testFlatMap(){

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

nums.add(Arrays.asList(1,2,3,4));

nums.add(Arrays.asList(5,6,7,8));

nums.add(Arrays.asList(9,10,11,12));

nums.add(Arrays.asList(13,14,15,16));

List<Integer> collect = nums.stream().flatMap(e -> e.stream()).collect(Collectors.toList());

System.out.println(collect);

}

mapToInt

针对每个元素 是否有转成int的需求

@Test

public void testMapToInt(){

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

names.add("wangcongming");

names.add("zhangsan");

names.add("lisi");

names.add("wangwang");

names.stream().mapToInt(e->e.length()).forEach(System.out::println);

}

Collectors工具类

Collectors是一个工具类,里面封装了很多方法,可以很方便的获取到一个 Collector 接口的实现类对 象,从而可以使用 collect() 方法,对流中的数据,进行各种各样的处理、整合。

Collectors.toList() : 将流中的数据,聚合到一个 List 集合中

Collectors.toSet() : 将流中的数据,聚合到一个 Set 集合中

Collectors.toMap() : 将流中的数据,聚合到一个 Map 集合中

maxBy() : 按照指定的规则,找到流中最大的元素,等同于 max

minBy() : 按照指定的规则,找到流中最小的元素,等同于 min

joining() : 将流中的数据拼接成一个字符串,注意:只能操作流中是String的数据

summingInt() : 将流中的数据,映射成 int 类型的数据,并求和

averagingInt() : 将流中的数据,映射成 int 类型的数据,并求平均值

summarizingInt() : 将流中的数据,映射成 int 类型的数据,并获取描述信息
// maxBy: 按照指定的规则,找到流中最大的元素,等同于 max

Student max = list.stream().collect(Collectors.maxBy((s1, s2) -> s1.getScore() -s2.getScore())).get();

System.out.println(max);

// minBy: 按照指定的规则,找到流中最小的元素,等同于 min

Student min = list.stream().collect(Collectors.minBy((s1, s2) -> s1.getScore() -s2.getScore())).get();

System.out.println(min);


// 将流中的数据,拼接起来

String s1 = list.stream().map(Student::getName).collect(Collectors.joining());

System.out.println(s1);

// 将流中的数据,拼接起来,以指定的分隔符进行分隔

String s2 = list.stream() .map(Student::getName) .collect(Collectors.joining(", "));

System.out.println(s2);

// 将流中的数据,拼接起来,以指定的分隔符进行分隔,并添加前缀和尾缀

String s3 = list.stream().map(Student::getName).collect(Collectors.joining(", ", "{", "}"));

System.out.println(s3);


// 将流中的数据,映射成 int 类型的数据,并求和

int sum = list.stream().collect(Collectors.summingInt(Student::getScore));

System.out.println(sum);


// 将流中的数据,映射成 int 类型的数据,并求平均值

double average = list.stream() .collect(Collectors.averagingInt(Student::getScore));

System.out.println(average);


// 将流中的数据,映射成 int 类型的数据,并获取描述信息

IntSummaryStatistics summaryStatistics = list.stream() .collect(Collectors.summarizingInt(Student::getScore));

System.out.println(summaryStatistics);

System.out.println(summaryStatistics.getCount());

System.out.println(summaryStatistics.getSum());

System.out.println(summaryStatistics.getMax());

System.out.println(summaryStatistics.getMin());

System.out.println(summaryStatistics.getAverage());

综合大栗子

需求 : 一个集合中存储了了若干个Student对象 , 要求查询出以下结果 :

  1. 所有及格的学生信息

  2. 所有及格的学生姓名

  3. 所有学生的平均成绩

  4. 班级的前3名(按照成绩)

  5. 班级的3-10名(按照成绩)

  6. 所有不不及格的学生平均成绩

  7. 将及格的学生 , 按照成绩降序输出所有信息

  8. 班级学生的总分
    public class Student {

private String name;

private int score;

public String getName() {

return name;

}

public int getScore() {

return score;

}

public Student(String name, int score) {

this.name = name;

this.score = score;

}

@Override

public String toString() {

return String.format("姓名 : %s, 成绩 : %d", name, score); }

}

import java.util.List;

import java.util.ArrayList;

import java.util.Collections;

import java.util.stream.Collectors;

public class Program {

public static void main(String[] args) {

// 0、实例化集合,存储学生对象

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

Collections.addAll(list,

new Student("xiaoming", 89),

new Student("xiaobai", 98),

new Student("xiaohei", 78),

new Student("xiaolv", 86),

new Student("xiaowang", 59),

new Student("xiaoxiao", 100)

);


// 所有及格的学生信息

list.stream().filter(s->s.getScore()>=60).forEach(System.out::println);

// 所有及格的学生姓名

list.stream().filter(s->s.getScore()>=60)

.map(Student::getName).forEach(System.out::println);

// 所有学生的平均成绩

double average=list.stream().mapToInt(Student::getScore().average().getAsDouble);

System.out.println(average);

// 班级的前3名(按照成绩)

List<Student> result1=list.stream().sorted((s1,s2)->s2.getScore()-s1.getScore()).limit(3).collect(Collectors.toList());

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

// 班级的3-10名(按照成绩)

List<Student> result2 = list.stream().sorted((s1, s2) -> s2.getScore() - s1.getScore()).limit(10).skip(2).collect(Collectors.toList());

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

// 所有不不及格的学生平均成绩

double average1 = list.stream().filter(s -> s.getScore() < 60).mapToInt(Student::getScore)

.average() .getAsDouble();

System.out.println(average1);

// 将及格的学生 , 按照成绩降序输出所有信息

list.stream().filter(s -> s.getScore() >= 60).sorted((s1, s2) -> s2.getScore() - s1.getScore()).forEach(System.out::println);

// 班级学生的总分

long sum = list.stream().mapToInt(Student::getScore).sum();

System.out.println(sum);

相关推荐
猿周LV4 分钟前
多线程进阶 : 八股文面试题 一 [Java EE 多线程 锁和死锁相关问题]
java·开发语言·java-ee
茂茂在长安15 分钟前
JAVA面试常见题_基础部分_Mysql调优
java·mysql·面试
enyp8026 分钟前
qt QTreeWidget`总结
开发语言·数据库·qt
m0_6845985330 分钟前
心理咨询小程序的未来发展
java·微信小程序·小程序开发·心理咨询小程序·心理测评小程序
以山河作礼。1 小时前
【机器学习】13.十大算法之一K均值算法(K-means)聚类详细讲解
算法·机器学习·均值算法
PXM的算法星球1 小时前
(java/Spring boot)使用火山引擎官方推荐方法向大模型发送请求
java·spring boot·火山引擎
web_132334214361 小时前
Java实战:Spring Boot application.yml配置文件详解
java·网络·spring boot
_DCG_1 小时前
选择排序算法
算法·排序算法·选择排序
神仙别闹1 小时前
基于C#+SQL Server设计与实现的教学管理信息系统
java·数据库·c#
啾啾Fun1 小时前
[java基础-JVM篇]2_垃圾收集器与内存分配策略
java·开发语言·jvm