目录
在Java8中,接口中的抽象方法默认被 public,abstract修饰符修饰,在Java8之前不允许普通方法存在接口中,在java8之后接口中可以存在普通方法,但是必须被static或者default修饰。
Lamda
好处:简化匿名内部类的调用
规范:使用lamda表达式需要依赖函数式接口
- 一个接口只有一个抽象方法
- 可以使用被static或者default修饰的方法
- 接口被@FunctionalInterface修饰
例子
如果lamda表达式只有一个返回值可以不写大括号和return语句
List<Integer> list = Arrays.asList(1, 3, 2, 9, 7);
list.forEach(item-> System.out.println("我是"+item));
Collections.sort(list,(o1,o2)->{return o2-o1;});
System.out.println(list);
Stream
+--------------------+ +------+ +------+ +---+ +-------+
| stream of elements +-----> |filter+-> |sorted+-> |map+-> |collect|
+--------------------+ +------+ +------+ +---+ +-------+
//获取集合中大于2、并且经过排序、平方去重的有序集合
List<Integer> numbers = Arrays.asList(3, 2, 2, 3, 7, 3, 5);
List<Integer> collect = numbers.stream()
.filter(item -> item > 2)
.sorted((o1, o2) ->{return o2.compareTo(o1);})
.map(i -> i * i)
.distinct()
.collect(Collectors.toList());
System.out.println(collect);
import java.util.ArrayList;
import java.util.Arrays;
import java.util.IntSummaryStatistics;
import java.util.List;
import java.util.Random;
import java.util.stream.Collectors;
import java.util.Map;
public class Java8Tester {
public static void main(String args[]){
System.out.println("使用 Java 8: ");
System.out.println("列表: " +strings);
count = strings.stream().filter(string->string.isEmpty()).count();
System.out.println("空字符串数量为: " + count);
count = strings.stream().filter(string -> string.length() == 3).count();
System.out.println("字符串长度为 3 的数量为: " + count);
filtered = strings.stream().filter(string ->!string.isEmpty()).collect(Collectors.toList());
System.out.println("筛选后的列表: " + filtered);
mergedString = strings.stream().filter(string ->!string.isEmpty()).collect(Collectors.joining(", "));
System.out.println("合并字符串: " + mergedString);
squaresList = numbers.stream().map( i ->i*i).distinct().collect(Collectors.toList());
System.out.println("Squares List: " + squaresList);
System.out.println("列表: " +integers);
IntSummaryStatistics stats = integers.stream().mapToInt((x) ->x).summaryStatistics();
System.out.println("列表中最大的数 : " + stats.getMax());
System.out.println("列表中最小的数 : " + stats.getMin());
System.out.println("所有数之和 : " + stats.getSum());
System.out.println("平均数 : " + stats.getAverage());
System.out.println("随机数: ");
random.ints().limit(10).sorted().forEach(System.out::println);
// 并行处理
count = strings.parallelStream().filter(string -> string.isEmpty()).count();
System.out.println("空字符串的数量为: " + count);
}
}
使用 Java 8:
列表: [abc, , bc, efg, abcd, , jkl]
空字符串数量为: 2
字符串长度为 3 的数量为: 3
筛选后的列表: [abc, bc, efg, abcd, jkl]
合并字符串: abc, bc, efg, abcd, jkl
Squares List: [9, 4, 49, 25]
列表: [1, 2, 13, 4, 15, 6, 17, 8, 19]
列表中最大的数 : 19
列表中最小的数 : 1
所有数之和 : 85
平均数 : 9.444444444444445
随机数:
-1743813696
-1301974944
-1299484995
-779981186
136544902
555792023
1243315896
1264920849
1472077135
1706423674
空字符串的数量为: 2
Optional
import java.util.Optional;
public class Java8Tester {
public static void main(String args[]){
Java8Tester java8Tester = new Java8Tester();
Integer value1 = null;
Integer value2 = new Integer(10);
// Optional.ofNullable - 允许传递为 null 参数
Optional<Integer> a = Optional.ofNullable(value1);
// Optional.of - 如果传递的参数是 null,抛出异常 NullPointerException
Optional<Integer> b = Optional.of(value2);
System.out.println(java8Tester.sum(a,b));
}
public Integer sum(Optional<Integer> a, Optional<Integer> b){
// Optional.isPresent - 判断值是否存在
System.out.println("第一个参数值存在: " + a.isPresent());
System.out.println("第二个参数值存在: " + b.isPresent());
// Optional.orElse - 如果值存在,返回它,否则返回默认值
Integer value1 = a.orElse(new Integer(0));
//Optional.get - 获取值,值需要存在
Integer value2 = b.get();
return value1 + value2;
}
}
运行结果:
$ javac Java8Tester.java
$ java Java8Tester
第一个参数值存在: false
第二个参数值存在: true
10
案例一:将一段字符串中的一部分进行排序
public static void main(String[] args) {
String str = "2-5-4-3-8-9";
Integer[] integers = Arrays.stream(str.split("-"))
.map(Integer::parseInt)
.sorted()
.toArray(Integer[]::new);
String s = Arrays.toString(integers).replaceAll(",", "-");
String substring = s.substring(1, s.length() - 1);
System.out.println(substring);
}
案例二:查询list集合中性别时女的数据,如果为空要输出默认值
public static void main(String[] args) {
List<UserEntity> userEntityList = new ArrayList<>();
UserEntity userEntityDefault = new UserEntity();
userEntityList.add(new UserEntity("1", "111", "male"));
userEntityList.add(new UserEntity("2", "222", "female"));
userEntityList.add(new UserEntity("3", "333", "male"));
userEntityList.add(new UserEntity("4", "444", "female"));
UserEntity userEntity1 = userEntityList.stream().filter(s-> Objects.equals(s.getO3(), "male")).findFirst().orElse(userEntityDefault);
System.out.println(userEntity1);
}
案例三
public class Trader{
private String name;
private String city;
public Trader(String n, String c){
this.name = n;
this.city = c;
}
public String getName(){
return this.name;
}
public String getCity(){
return this.city;
}
public void setCity(String newCity){
this.city = newCity;
}
public String toString(){
return "pojo1.Trader:"+this.name + " in " + this.city;
}
}
public class Transaction{
private Trader trader;
private int year;
private int value;
public Transaction(Trader trader, int year, int value)
{
this.trader = trader;
this.year = year;
this.value = value;
}
public Trader getTrader(){
return this.trader;
}
public int getYear(){
return this.year;
}
public int getValue(){
return this.value;
}
public String toString(){
return "{" + this.trader + ", " +
"year: "+this.year+", " +
"value:" + this.value +"}";
}
}
public class Test {
public static void main(String[] args) {
Trader raoul = new Trader("Raoul", "Cambridge");
Trader mario = new Trader("Mario","Milan");
Trader alan = new Trader("Alan","Cambridge");
Trader brian = new Trader("Brian","Cambridge");
Transaction transaction2 = new Transaction(brian, 2011, 300);
List<Transaction> transactions = Arrays.asList(
new Transaction(brian, 2011, 300),
new Transaction(raoul, 2012, 1000),
new Transaction(raoul, 2011, 400),
new Transaction(mario, 2012, 710),
new Transaction(mario, 2012, 700),
new Transaction(alan, 2012, 950)
);
//找出2011年发生的所有交易,并按交易额排序
List<Transaction> collect = transactions.stream().filter(transaction -> transaction.getYear() == 2011).sorted((o1,o2)->o1.getYear()-o2.getYear()).collect(Collectors.toList());
System.out.println(collect);
//交易员在哪些不同的城市工作过
List<String> collect1 = transactions.stream().map(transaction -> transaction.getTrader().getCity()).distinct().collect(Collectors.toList());
System.out.println(collect1);
//查找所有来自剑桥的交易员,并按姓名进行排序并且通过字符串连接返回
String cambridge = transactions.stream().filter(transaction -> transaction.getTrader().getCity().equals("Cambridge")).map(o1 -> o1.getTrader().getName()).distinct().sorted((o1, o2) -> o1.compareTo(o2)).collect(Collectors.joining(", "));
System.out.println(cambridge);
//有没有交易员在米兰工作
/**
* anyMatch表示,判断的条件里,任意一个元素成功,返回true
*
* allMatch表示,判断条件里的元素,所有的都是,返回true
*
* noneMatch跟allMatch相反,判断条件里的元素,所有的都不是,返回true
*/
Boolean milanTrader = transactions.stream().anyMatch(transaction ->transaction.getTrader().getCity().equals("milan"));
System.out.println(milanTrader);
//打印生活在剑桥的交易员的所有交易额
transactions.stream().filter(transaction -> transaction.getTrader().getCity().equals("Cambridge")).forEach(o1-> System.out.println(o1.getValue()));
//所有交易中,最高的交易额是多少
Optional<Integer> maxValue = transactions.stream()
.map(Transaction::getValue)
.distinct()
.reduce(Integer::max);
System.out.println(maxValue);
//最小交易额
Integer integer = transactions.stream()
.map(o1 -> o1.getValue())
.distinct()
.reduce(Integer::min).get();
// Optional<Integer> minValue = (Optional<Integer>) integer
System.out.println(integer);
//将一段字符串中的一部分进行排序
String str = "2-5-4-3-8-9";
String collect2 = Arrays.stream(str.split("-")).sorted((o1, o2) -> o1.compareTo(o2)).collect(Collectors.joining(","));
//
Transaction transaction3 = transactions.stream().filter(transaction -> transaction.getYear() == 2000).findFirst().orElse(transaction2);
System.out.println(transaction3);
}
}
[{pojo1.Trader:Brian in Cambridge, year: 2011, value:300}, {pojo1.Trader:Raoul in Cambridge, year: 2011, value:400}]
[Cambridge, Milan]
Alan, Brian, Raoul
false
300
1000
400
950
Optional[1000]
300
{pojo1.Trader:Brian in Cambridge, year: 2011, value:300}
flatMap()
package cn.eva.test.demo2;
import java.util.List;
class Course {
String name;
Course(String name) {
this.name = name;
}
String getName() {
return name;
}
}
class Student {
String name;
List<Course> courses;
Student(String name, List<Course> courses) {
this.name = name;
this.courses = courses;
}
List<Course> getCourses() {
return courses;
}
String getName() {
return name;
}
}
class Class {
String name;
List<Student> students;
Class(String name, List<Student> students) {
this.name = name;
this.students = students;
}
List<Student> getStudents() {
return students;
}
}
public static void main(String[] args) {
List<Class> classes = Arrays.asList(
new Class("Class A", Arrays.asList(
new Student("Alice", Arrays.asList(new Course("Math"), new Course("Science"))),
new Student("Bob", Arrays.asList(new Course("Math"), new Course("English")))
)),
new Class("Class B", Arrays.asList(
new Student("Charlie", Arrays.asList(new Course("Science"), new Course("History"))),
new Student("David", Arrays.asList(new Course("Math"), new Course("History")))
))
);
//获取所有班级的
List<String> studentNames = classes.stream()
.flatMap(cls -> cls.getStudents().stream()) // 将每个班级的学生展开成单独的流
.map(Student::getName)
.collect(Collectors.toList()); // 收集到一个列表中
//获取所有课程信息
List<String> courseNames = classes.stream()
.flatMap(cls -> cls.getStudents().stream()) // 将每个班级的学生展开成单独的流
.flatMap(student -> student.getCourses().stream()) // 将每个学生的课程展开成单独的流
.map(Course::getName) // 获取每门课程的名称
.collect(Collectors.toList()); // 收集到一个列表中
studentNames.forEach(System.out::println);
System.out.println("==============================================");
courseNames.forEach(System.out::println);
}
输出:
Alice
Bob
Charlie
David
==============================================
Math
Science
Math
English
Science
History
Math
History
文章介绍了Java8中的Lambda表达式的使用,如何简化匿名内部类的调用,以及StreamAPI进行数据处理和过滤的操作。同时,展示了Optional类在处理可能为null的值时的作用。文中包含多个实际案例,如字符串排序、集合筛选和聚合操作等。

2万+

被折叠的 条评论
为什么被折叠?



