新特性系列"/>
Java8新特性系列
Java Lambda简介
Lambda是Java8发版的重要特性,lambda表达式提供了一种使用表达式表示一个方法接口的方法。Lambda表达式就像一种方法,它提供形式参数的列表以及以这些参数表示的主体(可以是表达式或代码块)。
Lambda表达式还改进了Collection库。Java8添加了两个与Collection的批量数据操作相关的软件包,即java.util.function软件包和java.util.stream。流就像迭代器一样,但是具有很多额外的功能。总之,lambda表达式和流是Java编程的最大变化,因为泛型和注释已添加到该语言中。在本文中,我们将从简单示例到复杂示例,探索lambda表达式和流的功能。
Lambda表达式基本语法
// 1. 不需要参数,返回值为 5
() -> 5 // 2. 接收一个参数(数字类型),返回其2倍的值
x -> 2 * x // 3. 接受2个参数(数字),并返回他们的差值
(x, y) -> x – y // 4. 接收2个int型整数,返回他们的和
(int x, int y) -> x + y // 5. 接受一个 string 对象,并在控制台打印,不返回任何值(看起来像是返回void)
(String s) -> System.out.print(s)
Lambda表达式改进
上面简单介绍了Lambda基本的语法接口,接下来我们主要看下Lambda对于我们现有编码习惯的一些改变。
- for循环
String[] arr = {"jack", "wason", "link", "David"};
List<String> pers = Arrays.asList(arr);// 老的写法
for (String per : pers) {System.out.print(per + "; ");
}// lambda语法
pers.forEach((per) -> System.out.print(per + "; "));
上面的代码示例,lambda表达式可以将我们的代码减少到一行,使代码更加的简洁易懂。
- 匿名内部类
Java Lambda表达式的一个重要用法是简化某些匿名内部类
// 如果需要新建一个线程,一种常见的写法是这样
new Thread(new Runnable() {@Overridepublic void run() {System.out.println("Hello world!");}
}).start();// lambda语法
new Thread(() -> System.out.println("Hello world!")).start();
- 对集合排序
// 对集合排序
String[] pers = {"jack", "wason", "link", "David"};Arrays.sort(pers, new Comparator<String>() {@Overridepublic int compare(String s1, String s2) {return (s1pareTo(s2));}
});
System.out.println(new Gson().toJson(pers));// lambda语法
String[] pers = { "jack", "wason", "link", "David" };Arrays.sort(pers,(String s1,String s2) -> (s1pareTo(s2)));
System.out.println(new Gson().toJson(pers));//使用Lambda表达式pers列表中最后一个字母排序
Comparator<String> sortByLastLetter = (String s1,String s2) -> (s1.charAt(s1.length() - 1) - s2.charAt(s2.length() - 1));
Arrays.sort(pers,sortByLastLetter);
- Stream操作
流是普遍使用lambda的集合的包装。它们支持许多使用lambda的操作,例如映射,过滤器,限制,排序,计数,最小,最大,总和,收集等。
stream主要具有如下三点特性:
- stream不存储数据
- stream不改变源数据
- stream的延迟执行特性
我们通过一个示例来看下lambda流操作的便捷及强大之处,我们创建了一个Person类,并使用该类将一些数据添加到列表中,这些数据将在进一步的流操作中使用:
public class Person {private String userName, gender;private Integer height, weight;public Person(String userName, String gender, int height, int weight) {this.userName = userName;this.gender = gender;this.height = height;this.weight = weight;
}
// Getter and Setter
. . . . .
}
接下来我们初始化一些数据:
// java程序员列表
List<Person> pers = new ArrayList<Person>() {{add(new Person("Will", "male", 178, 80));add(new Person("Tamsen", "female", 155, 52));add(new Person("Floyd", "male", 168, 62));add(new Person("Wason", "female", 140, 70));add(new Person("Vere", "male", 120, 42));add(new Person("Json", "female", 127, 51));add(new Person("Shawn", "male", 130, 45));add(new Person("Jayden", "female", 154, 63));add(new Person("Demi", "male", 190, 100));add(new Person("Terry", "female", 180, 88));}
};
现在我们对列表数据进行相关的流操作:
// 打印所有人员的姓名
pers.forEach((p) -> System.out.println(p.getUserName()));// 将男性生高加5cm
Consumer<Person> personConsumer = e -> e.setHeight(e.getHeight() + 5);
pers.forEach(personConsumer);
pers.forEach((p) -> System.out.println(p.getUserName()+" : "+p.getHeight()));// 打印身高超过170cm的人员
pers.stream().filter((p) -> (p.getHeight() > 170)).forEach((p) -> System.out.println(p.getUserName() + " : " + p.getHeight()));// 定义多个过滤器过滤身高超过170cm的男性
Predicate<Person> heightFilter = (p) -> (p.getHeight() > 170);
Predicate<Person> genderFilter = (p) -> (p.getGender().equals("male"));pers.stream().filter(heightFilter).filter(genderFilter).forEach((p) -> System.out.println(p.getUserName() + " : " + p.getGender()+" : "+p.getHeight()));// 按身高进行排序,显示排名前三的人员
List<Person> sortPers=pers.stream().sorted((p1,p2)->(p2.getHeight()pareTo(p1.getHeight()))).limit(3).collect(Collectors.toList());
sortPers.forEach((p)-> System.out.println(p.getUserName()+" : "+p.getHeight()));// 获取身高最矮的人员
Person per=pers.stream().min((p1,p2)->(p1.getHeight()-p2.getHeight())).get();
System.out.println(per.getUserName()+" : "+per.getHeight());
同时通过流操作我们可以方便的将数据转换为string,Set等类型
// 将列表中姓名存放到string
String userNameStr = pers.stream().map(Person::getUserName).collect(joining(","));
System.out.println(userNameStr);// 将列表中姓名存放到set
Set<String> userNameSet = pers.stream().map(Person::getUserName).collect(toSet());
System.out.println(userNameSet);
同时有个非常有用的方法叫做 summaryStatistics()可以获得有关流元素的各种摘要数据,如:获取个数、最小值、最大值、总和以及平均值
// 获取身高的最大值,最小值,总和,平均值
IntSummaryStatistics stats = pers.stream().mapToInt((x) -> x.getHeight()).summaryStatistics();
System.out.println("Highest pers number in List : " + stats.getMax());
System.out.println("Lowest pers number in List : " + stats.getMin());
System.out.println("Sum of all pers numbers : " + stats.getSum());
System.out.println("Average of all pers numbers : " + stats.getAverage());
总结:
在本文中,我们发现了使用lambda表达式的不同方法,从基本示例到复杂的示例,其中我们都将lambda与流一起使用。此外,我们还学习了如何在Comparator类中使用lambda表达式对Java集合进行排序。
更多推荐
Java8新特性系列
发布评论