您的位置:首页 > 编程语言 > Java开发

关于Java函数式编程

2017-11-18 12:04 155 查看
最近在学习分布式治理框架,学习到服务调用模块时,了解到调用方式有1、同步调用; 2、异步调用;3、并发调用;其中并发调用可以使用到Fork/Join线程池的方式发起调用。第一次接触Fork/Join并发模式(以下简称FJ),所以就顺便了解下API。在试验FJ实现的二分排序时,打算用java.util.Random初始化一个数组,发现Random有生成stream的功能,我就很好奇,Random和Stream有什么关系。原来这里Stream和IO Stream是两码事,此Stream是操作流的的意思,进一步翻API和资料,原来这是JAVA实现Lambda函数式编程的一块内容。现在将今天翻阅的资料做个整理。

为啥要引入Lambda函数式编程,Lambda表达式的格式、java如何引入Lambda表达式的,这里很描述详细。

需要注意的是Lambda表达式里面This指的所包含的类,匿名类中的this是匿名类本身

点击打开链接

点击打开链接

这篇文章介绍了Java8引入了Interface的默认方法的原因:支持接口的扩展;带来的好处就是java.util.collection框架支持lambda函数表达式。

Interface引入default方法实现,同时也引入了多继承。但不支持Interface直接实例化对象,除非用在lambda表达式中

点击打开链接

这里有更多关于Lambda表达式使用的例子。不过我不认同作者说lambda表达式只是语法糖的说法,而是另一种编程思维方式。有利于扩大Java语言适用的领域

点击打开链接

经过测试,用stream来实现排序,效率时不高的。具体代码如下:

如果服务器CPU不多排序的数量级在万级以下,则使用Arrays.sort()足够了,如果服务器是多核的,且排序量大,只可以考虑使用递归并发排序。

package jdk;

import java.util.Arrays;
import java.util.Random;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.RecursiveAction;
import java.util.stream.LongStream;

public class ForkTaskTest {

static class SortTask extends RecursiveAction {
final long[] array;
final int lo, hi;

SortTask(long[] array, int lo, int hi) {
this.array = array;
this.lo = lo;
this.hi = hi;
}

SortTask(long[] array) {
this(array, 0, array.length);
}

protected void compute() {
if (hi - lo < THRESHOLD)
sortSequentially(lo, hi);
else {
int mid = (lo + hi) >>> 1;
invokeAll(new SortTask(array, lo, mid), new SortTask(array,
mid, hi));
merge(lo, mid, hi);
}
}

// implementation details follow:
static final int THRESHOLD = 1000;

void sortSequentially(int lo, int hi) {
Arrays.sort(array, lo, hi);
}

void merge(int lo, int mid, int hi) {
long[] buf = Arrays.copyOfRange(array, lo, mid);
for (int i = 0, j = lo, k = mid; i < buf.length; j++)
array[j] = (k == hi || buf[i] < array[k]) ? buf[i++]
: array[k++];
}
}

public static void main(String[] args) {
ForkJoinPool pool = new ForkJoinPool();
int i = 0;
long[] array = new long[9999999];
long[] a1 = new long[9999999];
long[] a2 = new long[9999999];
Random random = new Random();
while(i<9999999){
long randomLong = random.nextLong();
array[i] = randomLong;
a1[i] = randomLong;
a2[i] = randomLong;
i++;
}

SortTask task = new SortTask(array);
Long start = System.currentTimeMillis();
pool.invoke(task);
Long end = System.currentTimeMillis();
System.out.println(end - start);
start = System.currentTimeMillis();
Arrays.sort(a2);
end = System.currentTimeMillis();
System.out.println(end - start);

LongStream stream = Arrays.stream(a1);
start = System.currentTimeMillis();
long[] a3 = stream.sorted().toArray();
end = System.currentTimeMillis();
System.out.println(end - start);

long j = array[0];
for(i=0;i<9999999;i++){

if(array[i]!=a3[i]){
System.err.println("not equal");
}
if(j > array[i]){

System.err.println("not order");
}
j = array[i];
}
}

}
测试结果:

963     ---使用递归并发排序

1079   ---使用Arrays.sort, 这个算法比较稳定

1267   ---使用流式排序
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息