Java 8新特性
java8中 HashMap的数据结构由数组+链表 新增加了红黑树 这样 查找、删除产,修改的效率变高,新增的效率变慢。
堆区,栈区,方法区,方法区是堆区的一部分,位于永久区PremGen
Runnable runnable=() -> System.out.println("hello"+i); runnable.run();//输出hello0
左侧是接口方法的参数 右侧是接口要实现的功能
Consumer<String> con=(x) -> System.out.println(x); con.accept("ok"); //把ok传给上面输出 Consumer<String> con1=x -> System.out.println(x); con1.accept("ok"); //把ok传给上面输出
Lambda有多条语句的时候需要用大括号括起来:只有一条语句的时候
Comparator<Integer> com=(x,y) ->{ System.out.println("ok"); //输出ok return Integer.compare(x,y); }; Comparator<Integer> com2=(x,y) -> Integer.compare(x,y); int value=com.compare(1,2); //1比2大 System.out.println(value); System.out.println(com2.compare(1,2));
输出:
Stream API 和Lambda表达式:
List<Employee> employees= Arrays.asList( new Employee("a",1,1000), new Employee("b",24,8888), new Employee("b",31,9999), new Employee("b",77,11111) ); //获取薪水小于10000的员工 employees.stream().filter((e) -> e.getSalary()<10000) .forEach(System.out::println); //获取所有员工的名字 employees.stream() .map(Employee::getName) .forEach(System.out::println); }
参数的数据类型可以省略不写:
Lambda需要函数式接口的支持
MyFunction是一个泛型的接口 里面有一个String getValue()方法 返回String类型的值
案例:
接口
@FunctionalInterface //有这个注解的接口 只能有一个方法 public interface EmployeeDao { String say(String x); }
测试类:
@Test public void test1(){ /*String saying=say("hello",str -> str+"world");*/ String saying=say("hello",(String str) -> str+"world"); //(String str) 就是接口里面方法的参数形式 System.out.println(saying); } public String say(String s,EmployeeDao employeeDao){ return employeeDao.say(s); }
输出:
带泛型的接口:
@FunctionalInterface //有这个注解的接口 只能有一个方法 public interface EmployeeDao<T,R> { //T 是参数 R是返回值 R say(T t,R r); }
测试类
@Test public void test1(){ say("hello","world",(x,y) -> x+y); } public void say(String str1,String str2,EmployeeDao<String,String> employeeDao){ System.out.println(employeeDao.say(str1,str2)); }
结果输出:
前面需要自定义接口 才能使用Lambdab表达式太麻烦 下面使用java8中自定义的接口
案例:
消费型接口
@Test public void testConsumer(){ consummer(10000,(m) -> System.out.println("消费"+m+"元")); } //消费型接口 public void consummer(double money,Consumer<Double> conm){ //传过去参数 conm.accept(money); }
输出:
供给型接口:
@Test public void testSuply(){ //下面产生的整数是100以内的随机数 List<Integer> list=suply(5,() -> (int)(Math.random()*100)); for(Integer i:list){ System.out.println(i); } } //供给型接口 //需求 产生指定的个数的整数,并且放入集number合中 public List<Integer> suply(int number,Supplier<Integer> conm){ //传过去参数 List<Integer> list=new ArrayList<>(); for(int i=0;i<number;i++){ //产生一个整数 Integer value=conm.get(); list.add(value); } return list; }
输出:
函数型接口:
@Test public void testFunction(){ String newStr=function("hello",(str) -> str+"world"); System.out.println(newStr); } //函数型接口 public String function(String str, Function<String,String> f){ //(String,String) 前面是参数类型 后面是返回值类型 return f.apply(str); }
输出:
断言型接口:返回boolean值
@Test public void testPredicate(){ List<String> list=Arrays.asList("tom","jack","picke"); list=predicate(list,(str) -> str.startsWith("t")); for(int i=0;i<list.size();i++){ System.out.println(list.get(i)); } } //断言型接口 //需求 将满足条件的字符串加入带集合中 public List<String> predicate(List<String> list ,Predicate<String> predicate){ List<String> list1=new ArrayList<>(); for(String s:list){ if (predicate.test(s)){ list1.add(s); } } return list1; }
输出:
案例:
@Test public void test1(){ //collection集合創建流 List<String> list=new ArrayList<>(); Stream<String> srtream=list.stream(); //数组创建流 Integer integer[]=new Integer[12]; Stream<Integer> stream=Arrays.stream(integer); //Stream的静态方法 of()创建流 Stream<String> stream1=Stream.of("a","b","c"); //创建无限流 迭代的方式 Stream<String> stream2=Stream.iterate("hello",(x) -> x+"world"); stream2.limit(10).forEach(System.out::println); //创建无限流 生成的方式 Stream<Double> stream3=Stream.generate(() -> Math.random()*100); stream3.limit(10).forEach(System.out::println); }
输出:
@Test public void test2(){ List<Employee> employees= Arrays.asList( new Employee("a",1,1000), new Employee("b",24,8888), new Employee("b",31,9999), new Employee("b",77,11111) ); //中间操作 不会执行任何内容 只有在终止操作的时候一次性执行全部的内容 //filter 传入lambda表达式 获取salay大于1000的employee Stream<Employee> stream=employees.stream().filter((x) -> x.getSalary()>1000); //终止操作 stream.forEach(System.out::println); //跳过前一个 Stream<Employee> stream1=employees.stream().filter((x) -> x.getSalary()>1000).skip(1); //终止操作 stream1.forEach(System.out::println); }
输出:
@Test public void test3(){ List<String> list=Arrays.asList("aaa","bbb","ccc"); //将list中的值变成大写 Stream<String> stream=list.stream().map((str) -> str.toUpperCase()); stream.forEach(System.out::println); //list.stream()方法操做的是里面的元素 //提取employee的名字 List<Employee> employees= Arrays.asList( new Employee("a",1,1000), new Employee("b",24,8888), new Employee("b",31,9999), new Employee("b",77,11111) ); employees.stream().map((e) -> e.getSalary()).forEach(System.out::println); /*//得到的结果是流里面套流 Stream<Stream<Character>> stream1=list.stream().map(Note::filterCharacter); stream1.forEach((stream2) -> { stream2.forEach(System.out::println); });*/ //使用 优化上面的流套流 System.out.println("......"); list.stream().flatMap(Note::filterCharacter).forEach(System.out::println); } //提供一个函数供给上面使用 注意返回的是流 public static Stream<Character> filterCharacter(String str){ List<Character> list=new ArrayList<>(); for(Character character:str.toCharArray()){ list.add(character); } return list.stream(); }
输出结果:
@Test public void test4(){ List<String> list=Arrays.asList("tom","jack","picke"); list.stream().sorted().forEach(System.out::println); List<Employee> employees= Arrays.asList( new Employee("a",1,1000), new Employee("b",24,8888), new Employee("b",31,9999), new Employee("b",77,11111) ); employees.stream().sorted((e1,e2) ->{ if (e1.getName().equalsIgnoreCase(e2.getName())){ return e1.getAge().compareTo(e2.getAge()); }else { return e1.getAge().compareTo(e2.getAge()); } }).forEach(System.out::println); }
结果输出:
@Test public void test5(){ List<Employee> employees= Arrays.asList( new Employee("a",1,1000), new Employee("b",24,8888), new Employee("b",31,9999), new Employee("b",77,11111) ); //是不是所有的name=“b” boolean flag= employees.stream().allMatch((e) -> "b".equalsIgnoreCase(e.getName())); System.out.println(flag); //至少匹配一个元素 name="b" boolean flag2= employees.stream().anyMatch((e) -> "b".equalsIgnoreCase(e.getName())); System.out.println(flag2); //检查没有一个匹配name="b" boolean flag3= employees.stream().noneMatch((e) -> "b".equalsIgnoreCase(e.getName())); System.out.println(flag3); //找到第一个元素 返回一个容器类 Optional<Employee> optional=employees.stream().sorted((e1, e2) -> e1.getAge().compareTo(e2.getAge())).findFirst(); System.out.println(optional.get()); //找到任何一个元素 返回一个容器类 Optional<Employee> optional2=employees.stream().filter((e) -> "b".equalsIgnoreCase(e.getName())).findAny(); System.out.println(optional2.get()); }
结果输出:
@Test public void test6(){ List<Employee> employees= Arrays.asList( new Employee("a",1,1000), new Employee("b",24,8888), new Employee("b",31,9999), new Employee("b",77,11111) ); //返回流中总数 Long count=employees.stream().count(); System.out.println(count); //最大工资的employee Optional<Employee> optional=employees.stream().max((e1,e2) -> e1.getSalary().compareTo(e2.getSalary())); System.out.println(optional.get()); //的带最大employee的工资是多少 Optional<Integer> salary=employees.stream().map(Employee::getSalary).max((salarye1, salarye2) -> salarye1.compareTo(salarye2)); System.out.println(salary.get()); }
输出:
@Test public void test7(){ List<Employee> employees= Arrays.asList( new Employee("a",1,1000), new Employee("b",24,8888), new Employee("b",31,9999), new Employee("b",77,11111) ); //计算employee的总工资 总工资从2开始累加 //先把远编程工资 使用reduce //employees.stream().reduce(2,(x,y) -> x+y) 这种方式是错误的 stream得到的是employee的流 Integer sum=employees.stream().map(Employee::getSalary).reduce(2,(x,y) -> x+y); System.out.println(sum); }
结果:
@Test public void test8(){ List<Employee> employees= Arrays.asList( new Employee("a",1,1000), new Employee("b",24,8888), new Employee("b",31,9999), new Employee("b",77,11111) ); //收集所有员工的名字 List<String> list=employees.stream().map(Employee::getName).collect(Collectors.toList()); list.forEach(System.out::println); //收集到自发定义的集合中 HashSet<String> set=employees.stream().map(Employee::getName).collect(Collectors.toCollection(() -> new HashSet<>())); //上面的等同于HashSet<String> set=employees.stream().map(Employee::getName).collect(Collectors.toCollection(HashSet::new)); set.forEach(System.out::println); //总数 Long count=employees.stream().collect(Collectors.counting()); //平均值 Double avg=employees.stream().collect(Collectors.averagingInt(Employee::getSalary)); //总和 Double sun=employees.stream().collect(Collectors.averagingInt(Employee::getSalary)); //最大薪水 返回的是员工 Optional<Employee> optional=employees.stream().collect(Collectors.maxBy((e1,e2) -> e1.getSalary().compareTo(e2.getSalary()))); System.out.println(optional.get()); //最大薪水 返回的工资的值 Optional<Integer> optional2=employees.stream().map(Employee::getSalary).collect(Collectors.maxBy((x,y) ->x.compareTo(y))); System.out.println(optional2.get()); //分组 按姓名分组 Map<String,List<Employee>> employeeMap=employees.stream().collect(Collectors.groupingBy(Employee::getName)); System.out.println(employeeMap); System.out.println("........"); //多级分组 Map<String,Map<String,List<Employee>>> em=employees.stream().collect(Collectors.groupingBy(Employee::getName,Collectors.groupingBy( (e) ->{ if (e.getSalary()<3500){ return "低工资"; }else if (e.getSalary() <8000){ return "中等工资"; }else { return "高工资"; } } ))); System.out.println(em); //分区 按工资分区 Map<Boolean,List<Employee>> booleanListMap=employees.stream().collect(Collectors.partitioningBy((e) -> e.getSalary() <5000)); System.out.println(booleanListMap); //所有的name的值用逗号,连接在一起 String name=employees.stream().map(Employee::getName).collect(Collectors.joining(",")); System.out.println(name); }
结果输出:
a
b
b
b
a
b
Employee{name='b', age=77, salary=11111}
11111
{a=[Employee{name='a', age=1, salary=1000}], b=[Employee{name='b', age=24, salary=8888}, Employee{name='b', age=31, salary=9999}, Employee{name='b', age=77, salary=11111}]}
........
{a={低工资=[Employee{name='a', age=1, salary=1000}]}, b={高工资=[Employee{name='b', age=24, salary=8888}, Employee{name='b', age=31, salary=9999}, Employee{name='b', age=77, salary=11111}]}}
{false=[Employee{name='b', age=24, salary=8888}, Employee{name='b', age=31, salary=9999}, Employee{name='b', age=77, salary=11111}], true=[Employee{name='a', age=1, salary=1000}]}
Process finished with exit code 0
练习:
@Test public void test9(){ //给定一个数字列表,如何返回每个数字的平方 Integer num[]={1,2,3,4,5}; Arrays.stream(num).map((x) -> x*x).forEach(System.out::println); //用map和reduce计算有数组里有多少个数字 Optional<Integer> count=Arrays.stream(num).map((x) -> 1).reduce(Integer::sum); System.out.println(count.get()); List<Employee> employees= Arrays.asList( new Employee("a",1,1000), new Employee("b",24,8888), new Employee("b",31,8888), new Employee("b",77,11111) ); //找到name="b"的employee并且按照age 排序 employees.stream().filter((e) -> e.getName().equalsIgnoreCase("b")) //.sorted((e1,e2) -> Integer.compare(e1.getAge(),e2.getAge())); .sorted((e1,e2) ->e1.getAge().compareTo(e2.getAge())) .forEach(System.out::println); //员工的工资分别是多少 不重复 employees.stream().map(Employee::getSalary).distinct() .forEach(System.out::println); //返回所有employee的姓名并且按照字母排序 employees.stream().map(Employee::getName) .sorted((name1,name2) -> name1.compareTo(name2)) .forEach(System.out::println); //有没employe name="c" Boolean flag=employees.stream().allMatch((e) -> e.getName().equalsIgnoreCase("c")); System.out.println(flag); //employee的工资 Optional<Integer> optional=employees.stream().map(Employee::getSalary) .reduce(Integer::sum); System.out.println(optional.get()); //employee的最高工资 optional=employees.stream().map(Employee::getSalary).reduce((x,y) ->Integer.max(x,y)); System.out.println(optional.get()); //最小工资的employee Optional<Employee> o= employees.stream().collect(Collectors.minBy((e1,e2) -> e1.getSalary().compareTo(e2.getSalary()))); System.out.println(o.get()); }
结果:
其他的特性: