要使用lambda表达式,必须装1.8以上的Java版本(包括1.8)
一 stream(流)
1 通过filter过滤掉不满足条件的属性值(普通类型)
显示list集合中不是bb的所有值
public class FirstClass { @Test public void test() { List<String> list=new ArrayList(); list.add("aa"); list.add("bb"); list.add("cc"); list.add("dd"); list.add("ee"); list.stream().filter(s -> null!=s&&!"bb".equals(s)) .forEach(s -> System.out.println(s)); } }
.filter(条件表达式,就是判断语句)
.forEach(要循环的值),.forEach中的变量已经是过滤之后的了
2 通过.filter过滤引用类型,获取姓名不是aa对象的年龄
public class FirstClass { @Test public void test() { Person person = new Person(); person.setName("aa"); person.setAge(10); Person person1 = new Person(); person1.setName("bb"); person1.setAge(11); Person person2 = new Person(); person2.setName("cc"); person2.setAge(12); List<Person> list=new ArrayList(); list.add(person); list.add(person1); list.add(person2); list.stream().filter(p ->!p.getName().equals("aa")) .forEach(p->{ System.out.println(p.getAge()); } ); } }
3 若是只想做一下过滤,不想输出,需要把过滤结果给其他人使用,怎么办?
.collect 是将.filter过滤完成的结果转为一个新的集合,需要用变量接收
import lombok.Data; @Data public class Person { private int age; private String name; } import org.junit.Test; import java.util.*; import java.util.stream.Collectors; public class FirstClass { @Test public void test() { Person person = new Person(); person.setName("aa"); person.setAge(10); Person person1 = new Person(); person1.setName("bb"); person1.setAge(11); Person person2 = new Person(); person2.setName("cc"); person2.setAge(12); List<Person> list=new ArrayList(); list.add(person); list.add(person1); list.add(person2); List list1=list.stream().filter(p ->!p.getName().equals("aa")) .collect(Collectors.toList()); for(int i=0;i<list1.size();i++){ System.out.println(list1.get(i)); } } }
4 set集合也可以用.collect接收过滤后的结果
import lombok.Data; @Data public class Person { private int age; private String name; } import org.junit.Test; import java.util.*; import java.util.stream.Collectors; public class FirstClass { @Test public void test() { Person person = new Person(); person.setName("aa"); person.setAge(10); Person person1 = new Person(); person1.setName("bb"); person1.setAge(11); Person person2 = new Person(); person2.setName("cc"); person2.setAge(12); Set<Person> set=new HashSet<>(); set.add(person); set.add(person1); set.add(person2); Set set1=set.stream().filter(p ->!p.getName().equals("aa")) .collect(Collectors.toSet()); Iterator iterator=set1.iterator(); while (iterator.hasNext()){ Person s=(Person) iterator.next(); System.out.println(s.getName()); } } }
5 其实特性
limit 例:List.stream().limit(2)返回前两个集合
import lombok.Data; @Data public class Person { private int age; private String name; } import org.junit.Test; import java.util.*; import java.util.stream.Collectors; public class FirstClass { @Test public void test() { Person person = new Person(); person.setName("aa"); person.setAge(10); Person person1 = new Person(); person1.setName("bb"); person1.setAge(11); Person person2 = new Person(); person2.setName("cc"); person2.setAge(12); List list=new ArrayList(); list.add(person); list.add(person1); list.add(person2); list.stream().limit(2).forEach(f->{ System.out.println(f); }); } }
6 count 例:List.stream().count()返回长度大小,与list.size()一个功能
public class Person { private int age; private String name; } import org.junit.Test; import java.util.*; import java.util.stream.Collectors; public class FirstClass { @Test public void test() { Person person = new Person(); person.setName("aa"); person.setAge(10); Person person1 = new Person(); person1.setName("bb"); person1.setAge(11); Person person2 = new Person(); person2.setName("cc"); person2.setAge(12); List list=new ArrayList(); list.add(person); list.add(person1); list.add(person2); long a=list.stream().count(); System.out.println(a); } }
7 findFirst 例:Optional p=list.stream().findFirst();返回集合中的第一个对象要用Optional接收,写入泛型类型
public class Person { private int age; private String name; } import org.junit.Test; import java.util.*; import java.util.stream.Collectors; public class FirstClass { @Test public void test() { Person person = new Person(); person.setName("aa"); person.setAge(10); Person person1 = new Person(); person1.setName("bb"); person1.setAge(11); Person person2 = new Person(); person2.setName("cc"); person2.setAge(12); List list=new ArrayList(); list.add(person); list.add(person1); list.add(person2); Optional<Person> p=list.stream().findFirst(); System.out.println(p); } }
8 Map就是将某个List内容转换成Map
例把两个人的年龄放到一个新的List里,map里的语法叫函数式接口
语法(引用类型::方法名),就是遍历引用类型Person类,调用getName方法,将获取到的name放在一个新的集合list1里
public class Person { private int age; private String name; } import org.junit.Test; import java.util.*; import java.util.stream.Collectors; public class FirstClass { @Test public void test() { Person person = new Person(); person.setName("aa"); person.setAge(10); Person person1 = new Person(); person1.setName("bb"); person1.setAge(11); Person person2 = new Person(); person2.setName("cc"); person2.setAge(12); List<Person> list=new ArrayList(); list.add(person); list.add(person1); list.add(person2); List list1=list.stream().map(Person::getName).collect(Collectors.toList()); for(int i=0;i<list1.size();i++){ System.out.println(list1.get(i)); } } }
9 将List集合里的对象年龄相加,mapToInt(Person::getAge),还可以mapToDouble还可mapToIong
public class Person { private int age; private String name; } import org.junit.Test; import java.util.*; import java.util.stream.Collectors; public class FirstClass { @Test public void test() { Person person = new Person(); person.setName("aa"); person.setAge(10); Person person1 = new Person(); person1.setName("bb"); person1.setAge(11); Person person2 = new Person(); person2.setName("cc"); person2.setAge(12); List<Person> list=new ArrayList(); list.add(person); list.add(person1); list.add(person2); int ageSum=list.stream().mapToInt(Person::getAge).sum(); System.out.println(ageSum); } }
map里要是一般值,不是对象怎么取值,直接get(“Key”)就好 @org.testng.annotations.Test public void mapTest(){ List<Map<String,String>> mapList=new ArrayList<>(); Map<String,String> map =new HashMap<>(); map.put("userName","aa" ); map.put("age","十岁" ); map.put("sex","女" ); Map<String,String> map1 =new HashMap<>(); map1.put("userName","bb" ); map1.put("age","九岁" ); map1.put("sex","男" ); mapList.add(map); mapList.add(map1); List<Map<String,String>> mapList1=mapList.stream(). filter(m ->m.get("userName"). equalsIgnoreCase("bb")). collect(Collectors.toList()); for (Map m:mapList1){ System.out.println(m); } }
10 去重
Distinct:将多个相同内容只保留一个,与set相似,相同元素,只保留一个;据说对象去重要重写HashCode,但是下面这段代码并没有重写HashCode也实现了对象去重
public class Person { private int age; private String name; } import org.junit.Test; import java.util.*; import java.util.stream.Collectors; public class FirstClass { @Test public void test() { Person person = new Person(); person.setName("aa"); person.setAge(10); Person person1 = new Person(); person1.setName("aa"); person1.setAge(10); Person person2 = new Person(); person2.setName("aa"); person2.setAge(10); List<Person> list=new ArrayList(); list.add(person); list.add(person1); list.add(person2); list.stream().distinct().forEach(p->{ System.out.println(p); } ); } }
11 对象排序方法1
对象排序要指定一个属性,因为对象中有很多个属性(例如:name、age、sex…),并不知道要用哪个属性排序
(Person p1,Person p2)指定的属性p1和p2是两两对比,调用的就是排序方法,排序用的是ASCII码表顺序作为排序依据
public class Person { private int age; private String name; } import org.junit.Test; import java.util.*; import java.util.stream.Collectors; public class FirstClass { @Test public void test() { Person person = new Person(); person.setName("bb"); person.setAge(10); Person person1 = new Person(); person1.setName("zz"); person1.setAge(11); Person person2 = new Person(); person2.setName("xx"); person2.setAge(12); List<Person> list=new ArrayList(); list.add(person); list.add(person1); list.add(person2); list.sort((Person p1,Person p2) ->p1.getName().compareTo(p2.getName())); list.forEach(p-> { System.out.println(p.getName()); }); } }
**12 对象排序方法2(返序)
list.stream().sorted(Comparator.comparing(Person::getName)); list.forEach(p-> { System.out.println(p.getName()); }); 输出的还是bb zz xx 那就是没有排,name用.stream()的方式干什么呢?返序
在.sorted()后面加上.reversed()做返序排序;返序完成之后是一个新的流,要用一个变量接收(看清楚,是List list 是Person不是String),才能用forEach打印,或者在当前流直接forEach**
public class Person { private int age; private String name; } import org.junit.Test; import java.util.*; import java.util.stream.Collectors; public class FirstClass { @Test public void test() { Person person = new Person(); person.setName("bb"); person.setAge(10); Person person1 = new Person(); person1.setName("zz"); person1.setAge(11); Person person2 = new Person(); person2.setName("xx"); person2.setAge(12); List<Person> list=new ArrayList(); list.add(person); list.add(person1); list.add(person2); list.stream().sorted(Comparator.comparing(Person::getName).reversed()).forEach(s ->{ System.out.println(s.getName()); }); } }
13 如何将对象存入map里,从map里取出?
public class Person { private int age; private String name; } import org.junit.Test; import java.util.*; import java.util.stream.Collectors; public class FirstClass { @Test public void test() { Person person = new Person(); person.setName("bb"); person.setAge(10); Person person1 = new Person(); person1.setName("zz"); person1.setAge(11); Person person2 = new Person(); person2.setName("xx"); person2.setAge(12); Map<String,Person> map=new HashMap<>(); map.put("AA",person ); map.put("BB",person1 ); map.put("CC",person2 ); Person p=map.get("AA"); System.out.println(p.getName()); } }
14 如果我们不知道key的时候要获取name=bb这个对象的age,要怎么做?
对于map而言有一个约定,key用字符串存储,在lambda操作map里的值用数组保存
public class Person { private int age; private String name; } import org.junit.Test; import java.util.*; import java.util.stream.Collectors; public class FirstClass { @Test public void test() { Person person = new Person(); person.setName("bb"); person.setAge(10); Person person1 = new Person(); person1.setName("zz"); person1.setAge(11); Person person2 = new Person(); person2.setName("xx"); person2.setAge(12); Map<String,Person> map=new HashMap<>(); map.put("AA",person ); map.put("BB",person1 ); map.put("CC",person2 ); map.forEach((k,v) ->{ if(v.getName().equals("bb")){ System.out.println(v.getAge()); } }); } }
15 在lambda表达式中操作Map里对象的值用数组保存
有3个老师,每个老师有2个属性:name、course,每个老师的姓名,所授课程不同,根据输入的课程判断该课程对应的老师是否与预期相同
1.Teacher 类
import lombok.Data; @Data public class Teacher { String name; String coures; }
老师1继承Teacher 类
public class Xiaohu extends Teacher { public Xiaohu(String name,String coures){ this.name=name; this.coures=coures; } }
老师2继承Teacher类
public class Xiaoli extends Teacher { public Xiaoli(String name,String coures){ this.name=name; this.coures=coures; } }
老师3继承Teacher类
public class Xiaowanzi extends Teacher{ public Xiaowanzi(String name,String coures){ this.name=name; this.coures=coures; } }
业务类:实例化老师,做逻辑判断,获取的teacher的名字用数组接收,要先定义一个数组
import org.junit.Test; import java.util.HashMap; import java.util.Map; import static org.junit.Assert.*; public class TeacherTest { public String teacherTest(String coures){ Xiaoli xiaoli=new Xiaoli("xiaoli","java"); Xiaohu xiaohu=new Xiaohu("xiaohu","APP"); Xiaowanzi xiaowanzi=new Xiaowanzi("xiaowanzi","seleium"); Map<String,Teacher> teacherMap =new HashMap<>(); teacherMap.put("xiaoli", xiaoli); teacherMap.put("xiaohu",xiaohu); teacherMap.put("xiaowanzi", xiaowanzi); String [] name=new String[1]; teacherMap.forEach((k,v) ->{ if(v.getCoures().equals(coures)){ name[0]=v.getName(); }}); return name[0]; }
测试类,做检查点 @Test public void test(){ String name=teacherTest("java"); assertEquals("校验老师名字","xiaoli" ,name); } } assertEquals引import static org.junit.Assert.*;包,别引错包,第一个参数是输出文案,第二个参数是预期结果,第三个参数是实际结果