1.Java8的新特性带给了我们哪些好处?
- Lambda表达式
- 函数式接口
- 方法引用和构造器引用
- Stream API
- 接口的默认方法和静态方法
- 新时间日期API
- 其他新特性
这篇文章我们主要来康康Lambda表达式带给我们好处:
- 我们先创建一个Person人员信息的实体类:
public class Person {
private String name;
private Integer id;
public Person() {
}
public Person(String name, Integer id) {
this.name = name;
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
@Override
public String toString() {
return "Person [name=" + name + ", id=" + id + "]";
}
}
2.然后在把一些人员信息的对象存放在List集合中,这时候如果说我们有一个需求:需要查询出id大于20的人员信息
//创建一个Person类,并创建几个Person对象放在List集合中
List<Person> list=Arrays.asList(//asList:把数组中的元素传换成List元素
new Person("UZI",55),
new Person("小猪",44),
new Person("小狗",33),
new Person("The shy",22)
);
//需求:需要查询出id大于20的人员信息
public static List<Person> personlist(List<Person> lists){
//创建一个存放id大于20的人员信息
List<Person> arrayList = new ArrayList<Person>();
for (Person person : lists) {
if(person.getId() >=20){
arrayList.add(person);
}
}
return arrayList;
}
@Test
public void test1(){
List<Person> lists= TestLambda1.personlist(list);
for (Person person : lists) {
System.out.println(person);
}
}
3.如果这时候傻比老板又给你提了一个需求:查询小于40的人员信息
public static List<Person> personlist1(List<Person> lists){
//创建一个存放id大于20的人员信息
List<Person> arrayList = new ArrayList<Person>();
for (Person person : lists) {
if(person.getId() <=40){
arrayList.add(person);
}
}
return arrayList;
}
@Test
public void test2(){
List<Person> lists= TestLambda1.personlist1(list);
for (Person person : lists) {
System.out.println(person);
}
}
虽然,需求确实完成了,但是这样不仅显得代码过于冗余繁琐,还让自己累个半死,就得不偿失了。关键的代码就那么几行:
if(person.getId() …xxx){
arrayList.add(person);
}
所以,为了节省我们的时间,我们可以提出优化方案
方案1:采用策略设计模式
1.先创建一个接口
public interface LambdaMethod <T>{
//创建一个接口,这个接口有一个方法
public Boolean test(T t);
}
2.如果这时候傻B老板给你提出需求(比如查询出ID大于40的人员信息), 就可以直接去创建一个接口实现类,去完成需求方法:
public class ImpMethod implements LambdaMethod<Person>{
@Override
public Boolean test(Person t) {
if(t.getId()>40){
return true;
}else{
return false;
}
}
}
3.直接在添加方法中传入一个我们写的需求实现类:
public static List<Person> personlist2(List<Person> lists,LambdaMethod<Person> method){
//创建一个存放id大于40的人员信息
List<Person> arrayList = new ArrayList<Person>();
for (Person person : lists) {
if(method.test(person)){
arrayList.add(person);
}
}
return arrayList;
}
@Test
public void test3(){
List<Person> lists= TestLambda1.personlist2(list,new ImpMethod());
for (Person person : lists) {
System.out.println(person);
}
}
当然除了策略设计模式,我们还可以使用匿名内部类的方式:
方案2:匿名内部类
还是上面的添加方法,只不过我们传进去的不是已经实现需要的一个实现类了,而是直接使用匿名内部类的方式,添加一个匿名的实现类来实现方法:
@Test
public void test4(){
List<Person> lists= TestLambda1.personlist2(list,new LambdaMethod<Person>() {
@Override
public Boolean test(Person t) {
if(t.getId()<=40){
return true;
}
return false;
}
});
for (Person person : lists) {
System.out.println(person);
}
}
上面两个方案其实都是可以优化的,但是还是感觉太冗余,那么我们可以试试JDK1.8的Stream和Lambda表达式,看看它们是如何优化的。
方案3(java8):Lambda表达式(只需要一句代码就可以优化)
@Test
//查询出id小于50的人员信息
public void test5(){
List<Person> personlist2 = personlist2(list, (e) ->e.getId()<=50);
personlist2.forEach(System.out::println);
}
方案4:stream
@Test
//查询出id大于30的人员信息
public void test6(){
list.stream()
.filter((e) ->e.getId()>=30)
.limit(2)//从查询的结果集中取两条数据,按照最高的取:44 55
.forEach(System.out::println);
System.out.println("====================");
而且我们还可以直接一句代码查询出所有的人员信息:
list.stream()
.map(Person::getName)
.forEach(System.out::println);
}