用wordpress搭建网站,代码网站推荐,域名网络的解析网站,wordpress 微商城模板下载1.Lambda 1.1 格式 JDK 从 1.8 版本开始支持 Lambda 表达式#xff0c;通过 Lambda 表达式我们可以将一个函数作为参数传入方法中。在 JDK 1.8 之前#xff0c;我们只能通过匿名表达式来完成类似的功能#xff0c;但是匿名表达式比较繁琐#xff0c;存在大量的模板代码通过 Lambda 表达式我们可以将一个函数作为参数传入方法中。在 JDK 1.8 之前我们只能通过匿名表达式来完成类似的功能但是匿名表达式比较繁琐存在大量的模板代码不利于将行为参数化而采用 Lamdba 则能很好的解决这个问题。Lambda 表达式的基本语法如下 (parameters) - expression 或采用花括号的形式 (parameters) - { statements; } Lambda 表达式具有如下特点 可选的参数不需要声明参数类型编译器会依靠上下文进行自动推断 可选的参数圆括号当且仅当只有一个参数时包裹参数的圆括号可以省略 可选的花括号如果主体只有一个表达式则无需使用花括号 可选的返回关键字如果主体只有一个表达式则该表达式的值就是整个 Lambda 表达式的返回值此时不需要使用 return 关键字进行显式的返回。 1.2 行为参数化 上面我们说过Lambda 表达式主要解决的是行为参数化的问题而什么是行为参数化下面给出一个具体的示例 /*** 定义函数式接口* param T 参数类型*/
FunctionalInterface
public interface CustomPredicateT {boolean test(T t);
}
/*** 集合过滤* param list 待过滤的集合* param predicate 函数式接口* param T 集合中元素的类型* return 满足条件的元素的集合*/
public static T ListT filter(ListT list, CustomPredicateT predicate) {ArrayListT result new ArrayList();for (T t : list) {// 将满足条件的元素添加到返回集合中if (predicate.test(t)) result.add(t);}return result;
} 针对不同类型的集合我们可以通过传入不同的 Lambda 表达式作为参数来表达不同的过滤行为这就是行为参数化 ListInteger integers Arrays.asList(1, 2, 3, 4, 5);
filter(integers, x - x % 2 0); // 过滤出所有偶数ListEmployee employees Arrays.asList(new Employee(张某, 21, true),new Employee(李某, 30, true),new Employee(王某, 45, false));
filter(employees, employee - employee.getAge() 25); // 过滤出所有年龄大于25的员工 需要注意的是上面我们声明接口时使用了 FunctionalInterface 注解它表示当前的接口是一个函数式接口。函数式接口就是只含有一个抽象方法的接口即一个接口不论含有多少个默认方法和静态方法只要它只有一个抽象方法它就是一个函数式接口。使用 FunctionalInterface 修饰后当该接口有一个以上的抽象方法时编译器就会进行提醒。 任何使用到函数式接口的地方都可以使用 Lambda 表达式进行简写。例如 Runnable 接口就是一个函数式接口我们可以使用 Lambda 表达式对其进行简写 new Thread(() - {System.out.println(hello);
});1.3 方法引用和构造器引用 紧接上面的例子如果我们需要过滤出所有的正式员工除了可以写成下面的形式外 filter(employees, employee - employee.isOfficial()); 还可以使用方法引用的形式进行简写 filter(employees, Employee::isOfficial); 除了方法引用外还可以对构造器进行引用示例如下 StreamInteger stream Stream.of(1, 3, 5, 2, 4);
stream.collect(Collectors.toCollection(ArrayList::new)); //等价于 toCollection(()-new ArrayList()) 方法引用和构造器引用的目的都是为了让代码更加的简洁。 2. 函数式接口 通常我们不需要自定义函数式接口JDK 中内置了大量函数式接口基本可以满足大多数场景下的使用需求最基本的四种如下 2.1. ConsumerT消费型接口 消费输入的变量没有返回值 FunctionalInterface
public interface ConsumerT {void accept(T t);...
} 2.2 ConsumerT供给型接口 供给变量 FunctionalInterface
public interface SupplierT {T get();
} 2.3 FunctionT, R 对输入类型为 T 的变量执行特定的转换操作并返回类型为 R 的返回值 FunctionalInterface
public interface FunctionT, R {R apply(T t);...
} 2.4 PredicateT 判断类型为 T 的变量是否满足特定的条件如果满足则返回 true否则返回 false FunctionalInterface
public interface PredicateT {boolean test(T t);...
} 其他函数式接口都是这四种基本类型的扩展和延伸。以 BiFunction 和 BinaryOperator 接口为例 BiFunctionT, U, R是函数型接口 FunctionT, R 的扩展Function 只能接收一个入参而 BiFunction 可以用于接收两个不同类型的入参 BinaryOperatorT是 BiFunction 的一种特殊化情况即两个入参和返回值的类型均相同通常用于二元运算。定义如下 FunctionalInterface
public interface BiFunctionT, U, R {R apply(T t, U u);
}FunctionalInterface
public interface BinaryOperatorT extends BiFunctionT,T,T {....
} 下面演示一下 BinaryOperator 的用法 /* 执行归约操作*/
public static T T reduce(ListT list, T initValue, BinaryOperatorT binaryOperator) {for (T t : list) {initValue binaryOperator.apply(initValue, t);}return initValue;
}public static void main(String[] args) {ListInteger integers Arrays.asList(1, 2, 3, 4, 5);reduce(integers, 0, (a, b) - a b); // 求和 输出15reduce(integers, 1, (a, b) - a * b); // 求积 输出120
} 3. 创建流 JDK 1.8 中另一个大的改进是引入了流通过流、Lamda 表达式以及函数式接口可以高效地完成数据的处理。创建流通常有以下四种方法 3.1 由值创建 使用静态方法 Stream.of() 由指定的值进行创建 StreamString stream Stream.of(a, b, c, d); 3.2 由集合或数组创建 使用静态方法 Arrays.stream() 由指定的数组进行创建 String[] strings{a, b, c, d};
StreamString stream Arrays.stream(strings); 调用集合类的 stream() 方法进行创建 ListString strings Arrays.asList(a, b, c, d);
StreamString stream strings.stream(); stream() 方法定义在 Collection 接口中它是一个默认方法因此大多数的集合都可以通过该方法来创建流 public interface CollectionE extends IterableE {default StreamE stream() {return StreamSupport.stream(spliterator(), false);}
}3.3 由文件创建 try (StreamString lines Files.lines(Paths.get(pom.xml), StandardCharsets.UTF_8)) {lines.forEach(System.out::println);
} catch (IOException e) {e.printStackTrace();
} 3.4 由函数创建 除了以上方法外还可以通过 Stream.iterate() 和 Stream.generate() 方法来来创建无限流 Stream.iterate() 接受两个参数第一个是初始值第二个参数是一个输入值和输出值相同的函数型接口主要用于迭代式地产生新的元素示例如下 // 依次输出0到9
Stream.iterate(0, x - x 1).limit(10).forEach(System.out::print);
Stream.generate() 接收一个供应型函数作为参数用于按照该函数产生新的元素
// 依次输出随机数Stream.generate(Math::random).limit(10).forEach(System.out::print);4. 操作流 4.1 基本操作 当流创建后便可以利用 Stream 类上的各种方法对流中的数据进行处理常用的方法如下 操作 作用 返回类型 使用的类型/函数式接口 filter 过滤符合条件的元素 StreamT PredicateT distinct 过滤重复元素 StreamT skip 跳过指定数量的元素 StreamT long limit 限制元素的数量 StreamT long map 对元素执行特定转换操作 StreamT FunctionT,R flatMap 将元素扁平化后执行特定转换操作 StreamT FunctionT,StreamR sorted 对元素进行排序 StreamT ComparatorT anyMatch 是否存在任意一个元素能满足指定条件 boolean PredicateT noneMatch 是否所有元素都不满足指定条件 boolean PredicateT allMatch 是否所有元素都满足指定条件 boolean PredicateT findAny 返回任意一个满足指定条件的元素 OptionalT findFirst 返回第一个满足指定条件的元素 OptionalT forEach 对所有元素执行特定的操作 void CosumerT collect 使用收集器 R CollectorT, A, R reduce 执行归约操作 OptionalT BinaryOperatorT count 计算流中元素的数量 long 注上表中返回类型为 StreamT 的操作都是中间操作代表还可以继续调用其它方法对流进行处理。返回类型为其它的操作都是终止操作代表处理过程到此为止。 使用示例如下 Stream.iterate(0, x - x 1) // 构建流.limit(20) // 限制元素的个数.skip(10) // 跳过前10个元素.filter(x - x % 2 0) // 过滤出所有偶数.map(x - 偶数: x) // 对元素执行转换操作.forEach(System.out::println); // 打印出所有元素输出结果如下shell
偶数:10
偶数:12
偶数:14
偶数:16
偶数:18上表的 flatMap() 方法接收一个参数该参数是一个函数型接口 Function? super T, ? extends Stream? extends R mapper主要用于将流中的元素转换为 Stream 从而可以将原有的元素进行扁平化示例如下 String[] strings {hello, world};Arrays.stream(strings).map(x - x.split()) // 拆分得到: [h,e,l,l,o],[w,o,r,l,d].flatMap(x - Arrays.stream(x)) // 将每个数组进行扁平化处理得到h,e,l,l,o,w,o,r,l,d.forEach(System.out::println); 而上表的 reduce() 方法则接收两个参数第一个参数表示执行归约操作的初始值第二个参数是上文我们介绍过的函数式接口 BinaryOperatorT 使用示例如下 Stream.iterate(0, x - x 1).limit(10).reduce(0, (a, b) - a b); //进行求和操作4.2 数值流 上面的代码等效于对 Stream 中的所有元素执行了求和操作因此我们还可以调用简便方法 sum() 来进行实现但是需要注意的是 Stream.iterate() 生成流中的元素类型都是包装类型 StreamInteger stream Stream.iterate(0, x - x 1); //包装类型Integer
而 sum() 方法则是定义在 IntStream 上此时需要将流转换为具体的数值流对应的方法是 mapToInt()
Stream.iterate(0, x - x 1).limit(10).mapToInt(x - x).sum(); 类似的方法还有 mapToLong() 和 mapToDouble() 。如果你想要将数值流转换为原有的流相当于对其中的元素进行装箱操作此时可以调用 boxed() 方法 IntStream intStream Stream.iterate(0, x - x 1).limit(10).mapToInt(x - x);
StreamInteger boxed intStream.boxed();5.流收集器 5.1 常用流收集器 Stream 中最强大一个终止操作是 collect() 它接收一个收集器 Collector 作为参数可以将流中的元素收集到集合中或进行分组、分区等操作。Java 中内置了多种收集器的实现可以通过 Collectors 类的静态方法进行调用常用的收集器如下 工厂方法 返回类型 用于 toList ListT 把流中所有元素收集到 List 中 toSet SetT 把流中所有元素收集到 Set 中 toCollection CollectionT 把流中所有元素收集到指定的集合中 counting Long 计算流中所有元素的个数 summingInt Integer 将流中所有元素转换为整数并计算其总和 averagingInt Double 将流中所有元素转换为整数并计算其平均值 summarizingInt IntSummaryStatistics 将流中所有元素转换为整数并返回统计结果包含最大值、最小值、 总和与平均值等信息 joining String 将流中所有元素转换为字符串并使用给定连接符进行连接 maxBy OptionalT 查找流中最大元素的 Optional minBy OptionalT 查找流中最小元素的 Optional reducing 规约操作产生的类型 对流中所有元素执行归约操作 collectingAndThen 转换返回的类型 先把流中所有元素收集到指定的集合中再对集合执行特定的操作 groupingBy MapK,ListT 对流中所有元素执行分组操作 partitionBy MapBoolean,ListT 对流中所有元素执行分区操作 使用示例如下 StreamInteger stream Stream.of(1, 2, 3, 4, 4, 5, 6); stream.collect(Collectors.toSet()); // [1, 2, 3, 4, 5, 6]
stream.collect(Collectors.toList()); // [1, 2, 3, 4, 4, 5, 6]
stream.collect(Collectors.toCollection(ArrayList::new)); // [1, 2, 3, 4, 4, 5, 6]
stream.collect(Collectors.counting()); // 7 等效于 stream.count();
stream.collect(Collectors.summarizingInt(x - x)); // IntSummaryStatistics{count7, sum25, min1, average3.571429, max6}
stream.collect(Collectors.maxBy((Integer::compareTo))); // Optional[6]
stream.collect(Collectors.reducing(1, (a, b) - a * b)); // 等效于 stream.reduce(1, (a, b) - a * b);
collect(Collectors.collectingAndThen(Collectors.toSet(), Set::size)); // 先把所有元素收集到Set中再计算Set的大小 注意以上每个终止操作只能单独演示因为对一个流只能执行一次终止操作。并且执行完终止操作后就不能再对这个流进行任何操作否则将抛出 java.lang.IllegalStateException: stream has already been operated upon or closed 的异常。 5.2 分组收集器 分组收集器可以实现类似数据库 groupBy 子句的功能。假设存在如下员工信息 StreamEmployee stream Stream.of(new Employee(张某, 男, A公司, 20),new Employee(李某, 女, A公司, 30),new Employee(王某, 男, B公司, 40),new Employee(田某, 女, B公司, 50));
public class Employee {private String name;private String gender;private String company;private int age;Overridepublic String toString() {return Employee{ name name \ };}
} 此时如果需要按照公司进行分组则可以使用 groupingBy() 收集器 stream.collect(Collectors.groupingBy(Employee::getCompany));对应的分组结果如下
{ B公司[Employee{name王某}, Employee{name田某}], A公司[Employee{name张某}, Employee{name李某}]
} 如果想要计算分组后每家公司的人数还可以为 groupingBy() 传递一个收集器 Collector 作为其第二个参数调用其重载方法 stream.collect(Collectors.groupingBy(Employee::getCompany, Collectors.counting()));对应的结果如下
{B公司2, A公司2
} 因为第二个参数是一个 Collector这意味着你可以再传入一个分组收集器来完成多级分组示例如下 stream.collect(Collectors.groupingBy(Employee::getCompany, Collectors.groupingBy(Employee::getGender)));先按照公司分组再按照性别分组结果如下
{ B公司{女[Employee{name田某}], 男[Employee{name王某}]}, A公司{女[Employee{name李某}], 男[Employee{name张某}]}
} 除此之外也可以通过代码块来自定义分组条件示例如下 MapString, ListEmployee collect stream.collect(Collectors.groupingBy(employee - {if (employee.getAge() 30) {return 青年员工;} else if (employee.getAge() 50) {return 中年员工;} else {return 老年员工;}
}));对应的分组结果如下
{ 中年员工[Employee{name王某}], 青年员工[Employee{name张某}, Employee{name李某}], 老年员工[Employee{name田某}]
} 5.3 分区 分区是分组的一种特殊情况即将满足指定条件的元素分为一组将不满足指定条件的元素分为另一组两者在使用上基本类似示例如下 stream.collect(Collectors.partitioningBy(x - A公司.equals(x.getCompany())));对应的分区结果如下
{false[Employee{name王某}, Employee{name田某}], true[Employee{name张某}, Employee{name李某}]
} 6. 并行流 想要将普通流转换为并行流非常简单只需要调用 Stream 的 parallel() 方法即可 stream.parallel();此时流中的所有元素会被均匀的分配到多个线程上进行处理。并行流内部使用的是 ForkJoinPool 线程池它默认的线程数量就是处理器数量可以通过 Runtime.getRuntime().availableProcessors() 来查看该值通常不需要更改。 当前也没有办法为某个具体的流指定线程数量只能通过修改系统属性 java.util.concurrent.ForkJoinPool.common.parallelism 的值来改变所有并行流使用的线程数量示例如下 System.setProperty(java.util.concurrent.ForkJoinPool.common.parallelism,12); 如果想将并行流改回普通的串行流则只需要调用 Stream 的 sequential() 方法即可 stream.sequential(); 文章转载自: http://www.morning.fplwz.cn.gov.cn.fplwz.cn http://www.morning.rqgq.cn.gov.cn.rqgq.cn http://www.morning.jjnql.cn.gov.cn.jjnql.cn http://www.morning.qbdsx.cn.gov.cn.qbdsx.cn http://www.morning.qjsxf.cn.gov.cn.qjsxf.cn http://www.morning.qfkxj.cn.gov.cn.qfkxj.cn http://www.morning.snnkt.cn.gov.cn.snnkt.cn http://www.morning.gcjhh.cn.gov.cn.gcjhh.cn http://www.morning.hrzhg.cn.gov.cn.hrzhg.cn http://www.morning.kdxzy.cn.gov.cn.kdxzy.cn http://www.morning.rbgqn.cn.gov.cn.rbgqn.cn http://www.morning.gtxrw.cn.gov.cn.gtxrw.cn http://www.morning.dkcpt.cn.gov.cn.dkcpt.cn http://www.morning.xfyjn.cn.gov.cn.xfyjn.cn http://www.morning.qbwtb.cn.gov.cn.qbwtb.cn http://www.morning.brtxg.cn.gov.cn.brtxg.cn http://www.morning.pdkht.cn.gov.cn.pdkht.cn http://www.morning.htjwz.cn.gov.cn.htjwz.cn http://www.morning.grbgn.cn.gov.cn.grbgn.cn http://www.morning.mumgou.com.gov.cn.mumgou.com http://www.morning.jynzb.cn.gov.cn.jynzb.cn http://www.morning.pyxwn.cn.gov.cn.pyxwn.cn http://www.morning.qxrct.cn.gov.cn.qxrct.cn http://www.morning.hwnqg.cn.gov.cn.hwnqg.cn http://www.morning.kpzrf.cn.gov.cn.kpzrf.cn http://www.morning.ymjgx.cn.gov.cn.ymjgx.cn http://www.morning.jyznn.cn.gov.cn.jyznn.cn http://www.morning.tqrjj.cn.gov.cn.tqrjj.cn http://www.morning.xymkm.cn.gov.cn.xymkm.cn http://www.morning.bpmfn.cn.gov.cn.bpmfn.cn http://www.morning.bpmdn.cn.gov.cn.bpmdn.cn http://www.morning.hnhgb.cn.gov.cn.hnhgb.cn http://www.morning.qtbnm.cn.gov.cn.qtbnm.cn http://www.morning.rlbg.cn.gov.cn.rlbg.cn http://www.morning.kzbpx.cn.gov.cn.kzbpx.cn http://www.morning.mqfkd.cn.gov.cn.mqfkd.cn http://www.morning.gqjzp.cn.gov.cn.gqjzp.cn http://www.morning.dzfwb.cn.gov.cn.dzfwb.cn http://www.morning.gghhmi.cn.gov.cn.gghhmi.cn http://www.morning.pfgln.cn.gov.cn.pfgln.cn http://www.morning.jqlx.cn.gov.cn.jqlx.cn http://www.morning.btlmb.cn.gov.cn.btlmb.cn http://www.morning.wdply.cn.gov.cn.wdply.cn http://www.morning.pcgjj.cn.gov.cn.pcgjj.cn http://www.morning.qnhpq.cn.gov.cn.qnhpq.cn http://www.morning.gmmxh.cn.gov.cn.gmmxh.cn http://www.morning.crkmm.cn.gov.cn.crkmm.cn http://www.morning.gyxwh.cn.gov.cn.gyxwh.cn http://www.morning.xmjzn.cn.gov.cn.xmjzn.cn http://www.morning.wnzgm.cn.gov.cn.wnzgm.cn http://www.morning.tpkxs.cn.gov.cn.tpkxs.cn http://www.morning.qykxj.cn.gov.cn.qykxj.cn http://www.morning.fjtnh.cn.gov.cn.fjtnh.cn http://www.morning.qwnqt.cn.gov.cn.qwnqt.cn http://www.morning.kmbgl.cn.gov.cn.kmbgl.cn http://www.morning.czqqy.cn.gov.cn.czqqy.cn http://www.morning.xhlpn.cn.gov.cn.xhlpn.cn http://www.morning.rtbhz.cn.gov.cn.rtbhz.cn http://www.morning.ljhnn.cn.gov.cn.ljhnn.cn http://www.morning.bchhr.cn.gov.cn.bchhr.cn http://www.morning.plqqn.cn.gov.cn.plqqn.cn http://www.morning.fkdts.cn.gov.cn.fkdts.cn http://www.morning.jqrp.cn.gov.cn.jqrp.cn http://www.morning.ktcfl.cn.gov.cn.ktcfl.cn http://www.morning.lwtfx.cn.gov.cn.lwtfx.cn http://www.morning.gcfrt.cn.gov.cn.gcfrt.cn http://www.morning.fsnhz.cn.gov.cn.fsnhz.cn http://www.morning.wgkz.cn.gov.cn.wgkz.cn http://www.morning.mxxsq.cn.gov.cn.mxxsq.cn http://www.morning.kxymr.cn.gov.cn.kxymr.cn http://www.morning.fnnkl.cn.gov.cn.fnnkl.cn http://www.morning.slzkq.cn.gov.cn.slzkq.cn http://www.morning.fgxws.cn.gov.cn.fgxws.cn http://www.morning.lggng.cn.gov.cn.lggng.cn http://www.morning.mprky.cn.gov.cn.mprky.cn http://www.morning.hqrkq.cn.gov.cn.hqrkq.cn http://www.morning.qtrlh.cn.gov.cn.qtrlh.cn http://www.morning.cftkz.cn.gov.cn.cftkz.cn http://www.morning.yrjfb.cn.gov.cn.yrjfb.cn http://www.morning.lnfkd.cn.gov.cn.lnfkd.cn