通过Lambda把Java从强类型语言变成弱类型语言
通过Lambda可以使代码更加简洁。
Stream:
Java 8 API添加了一个新的抽象称为流Stream,可以让你以一种声明的方式处理数据。
Stream 使用一种类似用 SQL 语句从数据库查询数据的直观方式来提供一种对 Java 集合运算和表达的高阶抽象。
Stream API可以极大提高Java程序员的生产力,让程序员写出高效率、干净、简洁的代码。
这种风格将要处理的元素集合看作一种流, 流在管道中传输, 并且可以在管道的节点上进行处理, 比如筛选, 排序,聚合等。
例子1:做一个a+b方法
Stream 提供了新的方法 ‘forEach’ 来迭代流中的每个数据
普通写法:
public int add(int x, int y) { return x + y;//返回两数之和 }
Lambda写法:
(x, y) -> x + y; //返回两数之和
例子2:输出数组里的所有元素:
@Test public void a(){ int []a={1,2,3,4,5,6,7,8,9}; for(int i:a){ System.out.println(i); } List list= Arrays.asList(a); list .forEach(c->System.out.println(c)); }
可见λ表达式由三部分组成:参数列表,箭头(->),以及一个表达式或语句块。
下面我会用一个比较长例子来彻底理解Lambda
public class Person { private String firstName; private String lastName; private String job; private String gender; private int salary; private int age; public Person(){ } public Person(String firstName, String lastName){ this.firstName = firstName; this.lastName = lastName; } public Person(String firstName, String lastName, String job, String gender, int age, int salary) { this.firstName = firstName; this.lastName = lastName; this.gender = gender; this.age = age; this.job = job; this.salary = salary; } public String getFirstName() { return firstName; } public void setFirstName(String firstName) { this.firstName = firstName; } public String getLastName() { return lastName; } public void setLastName(String lastName) { this.lastName = lastName; } public String getJob() { return job; } public void setJob(String job) { this.job = job; } public String getGender() { return gender; } public void setGender(String gender) { this.gender = gender; } public int getSalary() { return salary; } public void setSalary(int salary) { this.salary = salary; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } }
public static List<Person> javaProgrammers = new ArrayList<Person>() { { add(new Person("Elsdon", "Jaycob", "Java programmer", "male", 43, 2000)); add(new Person("Tamsen", "Brittany", "Java programmer", "female", 23, 1500)); add(new Person("A", "Donny", "Java programmer", "male", 33, 1800)); add(new Person("Sindy", "Jonie", "Java programmer", "female", 32, 1600)); add(new Person("Vere", "Hervey", "Java programmer", "male", 22, 1200)); add(new Person("Maude", "Jaimie", "Java programmer", "female", 27, 1900)); add(new Person("Shawn", "Randall", "Java programmer", "male", 30, 2300)); add(new Person("Jayden", "Corrina", "Java programmer", "female", 35, 1700)); add(new Person("B", "Dene", "Java programmer", "male", 33, 1200)); add(new Person("Addison", "Pam", "Java programmer", "female", 34, 1300)); }
@Test public void ok() { Consumer<Person> t = e -> e.setSalary(e.getSalary() / 100 * 150); javaProgrammers.forEach(t); javaProgrammers.forEach(a -> System.out.println(a.getFirstName() + " " + a.getSalary())); }
public void predicate0() { Predicate<Person> pre = p -> p.getGender().equals("female"); Predicate<Person> pre1 = p -> p.getAge() > 30; //或 javaProgrammers.stream().filter(pre.or(pre1)).forEach(c -> System.out.println(c.getFirstName())); //与 javaProgrammers.stream().filter(pre).filter(pre1).forEach(c -> System.out.println(c.getFirstName())); }
第二种方法:
@Test public void predicate() { Predicate<Person> pre = p -> p.getGender().equals("female") && p.getAge() > 30; Predicate<Person> pre1 = p -> p.getGender().equals("female") || p.getAge() > 30; javaProgrammers.stream().filter(pre).forEach(a -> System.out.println(a.getFirstName())); javaProgrammers.stream().filter(pre1).forEach(a -> System.out.println(a.getFirstName())); }
@Test public void ok1() { javaProgrammers.stream().filter(p -> p.getGender().equals("male")).limit(3).forEach(p -> System.out.printf("%s %s\n", p.getFirstName(), p.getLastName())); }
@Test public void ok() { String s = null; Predicate<String> p = Objects::nonNull; System.out.println(p.test(s)); Predicate<String> p1 = Objects::isNull; System.out.println(p1.test(s)); String s2 = ""; Predicate<String> p2 = String::isEmpty; System.out.println(p2.test(s2)); }
@Test public void ok2() { Comparator<String> c = (p1, p2) -> p1.length() - p2.length();//比较的是字符串的长度 System.out.println(c.compare("aaa", "bbbb")); Comparator<String> c1 = (p1, p2) -> p1.compareTo(p2);//比较的是第一个不同字母的ASCII值 System.out.println(c1.reversed().compare("aaa", "Abbb"));//reversed是反过来 }
首先通过年龄进行比较,年龄相同时比较薪资
@Test public void ok4() { javaProgrammers.stream().sorted((p1, p2) -> p1.getAge() - p2.getAge() == 0 ? p1.getSalary() - p2.getSalary() : p1.getAge() - p2.getAge()).forEach(p -> System.out.println(p.getFirstName())); }
@Test public void ok6() { String[] a = {"哈工大", "清华", "西北工业大学"}; Function<String, String> f = c -> c + "第一";//map:映射 Arrays.asList(a).stream().map(f).collect(Collectors.toList()).forEach(System.out::println);//collect(Collectors.toList()):汇总。多线程更安全 System.out.println(javaProgrammers.stream().map(p->p.getFirstName()+"lala").collect(Collectors.joining("--")));//collect(Collectors.joining("--")):用--将数据分隔开 }
@Test public void ok8(){ List <Integer> a=Arrays.asList(100,200,300,400); a.stream().map(t->t*1.5).collect(Collectors.toList()).forEach(System.out::println);//通过映射给每个数扩大1.5倍 System.out.println(a.stream().map(t->t*1.5).reduce((t,sum)->sum+=t).get());//汇总 }
public List<String> stringCollection = new ArrayList<String>() { { add("aadde"); add("aaa"); add("aabbb"); } };
1字符串的匹配
@Test public void ok9(){ System.out.println(stringCollection.stream().anyMatch(s->s.startsWith("aaa")));//部分匹配 startsWith:前缀 System.out.println(stringCollection.stream().allMatch(s->s.startsWith("aaa")));//全部匹配 System.out.println(stringCollection.stream().noneMatch(s->s.endsWith("aaaaa")));//全不匹配 endsWith:后缀 }
@Test public void ok10(){ System.out.println(javaProgrammers.stream().filter(c->c.getGender().equals("male")).collect(Collectors.toList()).size()); System.out.println(javaProgrammers.stream().filter(p->p.getGender().equals("male")).count()); }
@Test public void ok11(){ List <Integer> numbers=Arrays.asList(1,2,3,4,5,6,7,8,9); numbers.parallelStream().forEach(System.out::println);//parallel:平行的。 parallelStream()是一个并行执行的流,通过默认的ForkJoinPool提高多线程任务的速度。 //Stream具有平行处理的能力,处理的过程会分而治之,也就是将一个大任务切分成多个小任务每个任务都是一个操作 numbers.parallelStream().forEachOrdered(System.out::println);//在池子中的多个线程中只用其中的一个线程,极大的浪费了资源 System.out.println("------------------------------"); numbers.stream().forEach(System.out::println); }
@Test public void ok12(){ List <Integer> numbers=Arrays.asList(1,2,3,4,5,6,7,8,9); IntSummaryStatistics is=numbers.parallelStream().mapToInt(x->x).summaryStatistics(); System.out.printf("MAX:%d---MIN:%d---AVG:%.2f----COUNT:%d---SUM:%d",is.getMax(),is.getMin(),is.getAverage(),is.getCount(),is.getSum()); }