做网站动图的软件游戏开发软件有哪些
news/
2025/10/4 16:38:28/
文章来源:
做网站动图的软件,游戏开发软件有哪些,上海网站建设公司选哪家好,cn网站建设多少钱一、简介
java8新添加了一个特性#xff1a;流Stream。Stream让开发者能够以一种声明的方式处理数据源#xff08;集合、数组等#xff09;#xff0c;它专注于对数据源进行各种高效的聚合操作#xff08;aggregate operation#xff09;和大批量数据操作 (bulk data op…一、简介
java8新添加了一个特性流Stream。Stream让开发者能够以一种声明的方式处理数据源集合、数组等它专注于对数据源进行各种高效的聚合操作aggregate operation和大批量数据操作 (bulk data operation)。
Stream API将处理的数据源看做一种Stream流Stream流在Pipeline管道中传输和运算支持的运算包含筛选、排序、聚合等当到达终点后便得到最终的处理结果。
几个关键概念
元素 Stream是一个来自数据源的元素队列Stream本身并不存储元素。数据源即Stream的来源包含集合、数组、I/O channel、generator发生器等。聚合操作 类似SQL中的filter、map、find、match、sorted等操作管道运算 Stream在Pipeline中运算后返回Stream对象本身这样多个操作串联成一个Pipeline并形成fluent风格的代码。这种方式可以优化操作如延迟执行(laziness)和短路( short-circuiting)。内部迭代 不同于java8以前对集合的遍历方式外部迭代Stream API采用访问者模式Visitor实现了内部迭代。并行运算 Stream API支持串行stream() 或并行parallelStream() 的两种操作方式。
Stream API的特点
Stream API的使用和同样是java8新特性的lambda表达式密不可分可以大大提高编码效率和代码可读性。Stream API提供串行和并行两种操作其中并行操作能发挥多核处理器的优势使用fork/join的方式进行并行操作以提高运行速度。Stream API进行并行操作无需编写多线程代码即可写出高效的并发程序且通常可避免多线程代码出错的问题。
二、简单示例
我们来看一个简单的示例统计整数数组中正数的个数
1.在java8之前 public static void main(String[] args){ ListInteger numbers Arrays.asList(-1, -2, 0, 4, 5);long count 0;for(Integer number: numbers){if(number 0){count;}}System.out.println(Positive count: count);}2.在java8之后 public static void main(String[] args){ ListInteger numbers Arrays.asList(-1, -2, 0, 4, 5);long count numbers.parallelStream().filter(i - i0).count();System.out.println(Positive count: count);}可以看到上例中使用filter()方法对数组进行了过滤使用count()方法对过滤后的数组进行了大小统计且使parallelStream()方法为集合创建了并行流自动采用并行运算提高速度。在更复杂的场景还可以用forEach()、map()、limit()、sorted()、collect()等方法进行进一步的流运算。
三、典型接口详解
本节以典型场景为例列出Stream API常用接口的用法并附上相应代码。 需要说明的是Stream API中存在很多方法重载同名方法本文中可能仅列举一个请读者注意~
3.1 Stream的生成
java8 Stream API支持串行或并行的方式可以简单看下jdk1.8 Collection接口的源码(注释只截取部分) /*** return a sequential {code Stream} over the elements in this collection* since 1.8*/default StreamE stream() {return StreamSupport.stream(spliterator(), false);}/*** return a possibly parallel {code Stream} over the elements in this collection* since 1.8*/default StreamE parallelStream() {return StreamSupport.stream(spliterator(), true);}可以看出在集合类的接口Collection中分别用两种方式来生成
串行流 stream()并行流 parallelStream()
应该注意的是使用parallelStream()生成并行流后对集合元素的遍历是无序的。
3.2 forEach()方法
简单看下forEach()方法的源码(注释只截取部分) /*** Performs an action for each element of this stream.*/void forEach(Consumer? super T action);forEach()方法的参数为一个Consumer消费函数一个函数式接口对象forEach()方法用来迭代流中的每一个数据例如 public static void main(String[] args){ ListInteger numbers Arrays.asList(-1, -2, 0, 4, 5);numbers.stream().forEach(n - System.out.println(List element: n));}上例中对数组的每个元素进行串行遍历并打印每个元素的值。
ps:
集合的顶层接口Iterable中也投forEach方法可以直接对数组元素进行遍历 public static void main(String[] args){ ListInteger numbers Arrays.asList(-1, -2, 0, 4, 5);numbers.forEach(n - System.out.println(List element: n));}当然用Strem API的好处不仅仅是遍历~~~
3.3 map()方法
简单看下map()方法的源码(注释只截取部分) /*** Returns a stream consisting of the results of applying the given function to the elements of this stream.* param R The element type of the new stream* param mapper a a hrefpackage-summary.html#NonInterferencenon-interfering/a,* a hrefpackage-summary.html#Statelessnessstateless/a* function to apply to each element* return the new stream*/R StreamR map(Function? super T, ? extends R mapper);map()方法的参数为Function函数式接口对象map()方法将流中的所有元素用Function对象进行运算生成新的流对象流的元素类型可能改变。举例如下 public static void main(String[] args){ ListInteger numbers Arrays.asList(-1, -2, 0, 4, 5);numbers.stream().map( n - Math.abs(n)).forEach(n - System.out.println(Element abs: n));}上例中用map()方法计算了所有数组元素的绝对值并生成了一个新的流然后再用forEach()遍历打印。
3.4 flatMap()方法
简单看下flatMap()方法的源码(省略注释) R StreamR flatMap(Function? super T, ? extends Stream? extends R mapper);显然跟map()方法不同的是Function函数的返回值类型是Stream? extends R类型而不是R类型即Function函数返回一个Stream流这样flatMap()能够将一个二维的集合映射成一个一维的集合比map()方法拥有更高的映射深度此处可能有一点绕可结合例子理解作个简单示例如下
有一个字符串数组:
ListString list Arrays.asList(1 2, 3 4, 5 6);其有三个元素每个元素有两个数组并用空格隔开如果每个元素以空格分割成2个元素并遍历打印这6个元素
用flatMap()方法如下
list.stream().flatMap(item - Arrays.stream(item.split( ))).forEach(System.out::println);而用map()方法 list.stream().map(item - Arrays.stream(item.split( ))).forEach(n -n.forEach(System.out::println));可见用map()方法返回了一个“流中流”需要在每个Stream元素遍历时再加一层forEach进行遍历。
3.5 filter()方法
简单看下filter()方法的源码(注释只截取部分)/*** Returns a stream consisting of the elements of this stream that match the given predicate.** pThis is an a hrefpackage-summary.html#StreamOpsintermediate operation/a.** param predicate a a hrefpackage-summary.html#NonInterferencenon-interfering/a,* a hrefpackage-summary.html#Statelessnessstateless/a* predicate to apply to each element to determine if it should be included* return the new stream*/StreamT filter(Predicate? super T predicate);filter()方法的参数为Predicate函数式接口对象再lambda表达式的讲解中我们提到过这个接口一般用它进行过滤。正如第二章中示例 public static void main(String[] args){ ListInteger numbers Arrays.asList(-1, -2, 0, 4, 5);long count numbers.parallelStream().filter(i - i0).count();System.out.println(Positive count: count);}用filter方法很容易过滤出整数数组中的自然数。
3.6 reduce()方法
reduce操作又称为折叠操作用于将流中的所有值合成一个。reduce()方法的源码不提供计算初始值的reduce方法省略注释
OptionalT reduce(BinaryOperatorT accumulator);reduce()方法参数为BinaryOperator类型的累加器它接受两个类型相同的参数返回值类型跟参数类型相同返回一个Optional对象。 实际上Stream API中的mapToInt()方法返回的IntStream接口有类似的 average()、count()、sum()等方法就是做reduce操作类似的还有mapToLong()、mapToDouble() 方法。当然我们也可以用reduce()方法来自定义reduce操作。例如我们用reduce()方法来进行整数数组求和操作 public static void main(String[] args){ListInteger numbers Arrays.asList(-1, -2, 0, -1, 4, 5, 1);Integer total numbers.stream().reduce((t, n) - t n).get();System.out.println(Total: total);}上例中利用reduce()方法结合lambda表达式轻易的实现了数组的求和功能。
3.7 collect()方法
简单看下collect()方法的源码(注释只截取部分) /*** param R the type of the result* param A the intermediate accumulation type of the {code Collector}* param collector the {code Collector} describing the reduction* return the result of the reduction*/R, A R collect(Collector? super T, A, R collector);collect()方法的参数为一个java.util.stream.Collector类型对象可以用java.util.stream.Collectors工具类提供的静态方法来生成Collectors类实现很多的归约操作如Collectors.toList()、Collectors.toSet()、Collectors.joining()joining适用于字符串流等。看一个简单示例 public static void main(String[] args){ ListInteger numbers Arrays.asList(-1, -2, 0, 4, 5);ListInteger abss numbers.stream().map( n - Math.abs(n)).collect(Collectors.toList());System.out.println(Abs list: abss);}上例中用map()方法生成新的流再用collect()方法返回原数组的绝对值数组。
3.8 summaryStatistics()方法进行数值统计
其实summaryStatistics()方法并不是Stream接口的方法而是Stream API采用mapToInt()、mapToLong()、mapToDouble()三个方法分别生成IntStream 、LongStream 、DoubleStream 三个接口类型的对象这个方法的参数分别为3个函数式接口ToIntFunction、ToLongFunction、ToDoubleFunction使用时可以用lambda表达式计算返回对应的int、long、double类型即可简单看下这三个方法的源码(省略注释) IntStream mapToInt(ToIntFunction? super T mapper);LongStream mapToLong(ToLongFunction? super T mapper);DoubleStream mapToDouble(ToDoubleFunction? super T mapper);IntStream 、LongStream 、DoubleStream 三个接口类型都有一个summaryStatistics()方法其中
IntStream 的方法是 IntSummaryStatistics summaryStatistics();LongStream 的方法是 LongSummaryStatistics summaryStatistics();DoubleStream 的方法是 DoubleSummaryStatistics summaryStatistics();在IntSummaryStatistics、LongSummaryStatistics 、DoubleSummaryStatistics 三个接口类型位于java.util包下中都有诸如统计数量、最大值、最小值、求和、平均值等方法方法名和返回类型可能不同利用这些方法我们可以方便的进行数值统计。以IntSummaryStatistics工具包 为例 public static void main(String[] args){ListInteger numbers Arrays.asList(-1, -2, 0, 4, 5);IntSummaryStatistics stats numbers.stream().mapToInt((x) - x).summaryStatistics();System.out.println(Max : stats.getMax());System.out.println(Min : stats.getMin());System.out.println(Sum : stats.getSum());System.out.println(Average : stats.getAverage());System.out.println(Count : stats.getCount());}3.9 其它方法
Stream API还有一些其它的方法比如 limit() 获取指定数量的流 sorted() 对流进行排序 distinct() 去重 skip() 跳过指定数量的元素 peek() 生成一个包含原Stream的所有元素的新Stream并指定消费函数 count() 计算元素数量 … 感兴趣的读者可以阅读源码读到这里已经很容易理解了本文不再赘述。
四、注意事项
Stream中的操作从概念上讲分为中间操作和终端操作
中间操作例如peek()方法提供Consumer消费函数但执行peek()方法时不会执行Consumer函数而是等到流真正被消费时终端操作时才进行消费才会执行这种操作为中间操作终端操作例如forEach()、collect()、count()等方法会对流中的元素进行消费并执行指定的消费函数peek方法提供的消费函数在此时执行这种操作为终端操作。 要理解中间操作和终端操作的概念防止埋坑~ 【java8新特性】——lambda表达式与函数式接口详解一 【java8新特性】——Stream API详解二 【java8新特性】——Optional详解三 【java8新特性】——方法引用四 【java8新特性】——默认方法五
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/927347.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!