函数式Java8中的冒泡排序
您将如何以功能(Java8)的方式实现下面的冒泡排序算法函数式Java8中的冒泡排序,java,sorting,java-8,functional-programming,bubble-sort,Java,Sorting,Java 8,Functional Programming,Bubble Sort,您将如何以功能(Java8)的方式实现下面的冒泡排序算法 publicstaticfinallist命令ubblesort(列表列表){ int len=list==null?0:list.size(); 对于(int j=len-1;j>0;j--){ 对于(int k=0;kresult.get(j+1).比较(result.get(j)){ T swap=结果。移除(j+1); 结果。添加(j,交换); 收益互换; }).count()>0) .max().ifPresent(IntCon
publicstaticfinallist命令ubblesort(列表列表){
int len=list==null?0:list.size();
对于(int j=len-1;j>0;j--){
对于(int k=0;k
这取决于您所说的功能。如果您的意思是将函数作为第一类对象传递,那么您应该将方法签名更改为:
public static final <T> List<T> imperativeBubbleSort(List<T> list, Comparator<T> comparisonFunction)
publicstaticfinallist命令式ubblesort(列表列表、比较器比较函数)
这样,比较逻辑可以作为参数提供
如果你的意思是完全功能化,而不是程序化,那么我会称之为反模式。尽管您可能听说过,Java8并不完全支持函数式编程。它缺少的一个关键特性是尾部调用优化。如果没有它,定义函数式编程的那种无循环编程很可能会因为相对较小的值而使JVM崩溃
关于尾部调用优化和JVM的更多信息可以在这里找到:我不认为Java8在这种情况下能为编写函数式冒泡排序提供太多帮助
public static final <T extends Comparable<T>> List<T> functionalBubbleSort(List<T> list) {
for (int i = 0; i < list.size(); i++) {
list = onePassSort(list);
}
return list;
}
public static final <T extends Comparable<T>> List<T> onePassSort(List<T> list) {
if (list.size() == 0 || list.size() == 1) {
return list;
} else {
T first = list.get(0);
T second = list.get(1);
if (first.compareTo(second) < 0) {
return merge(first, onePassSort(list.subList(1, list.size())));
} else {
return merge(second, onePassSort(merge(first, list.subList(2, list.size()))));
}
}
}
public static <T> List<T> merge(T head, List<T> tail) {
List<T> result = new ArrayList<>();
result.add(head);
result.addAll(tail);
return result;
}
例如,Haskell中气泡排序的实现可以在Java中模拟如下。它更具功能性,因为它使用递归而不是迭代,但Java8仍然缺乏
模式匹配、列表连接等功能,以更具功能性的方式表达算法
public static final <T extends Comparable<T>> List<T> functionalBubbleSort(List<T> list) {
for (int i = 0; i < list.size(); i++) {
list = onePassSort(list);
}
return list;
}
public static final <T extends Comparable<T>> List<T> onePassSort(List<T> list) {
if (list.size() == 0 || list.size() == 1) {
return list;
} else {
T first = list.get(0);
T second = list.get(1);
if (first.compareTo(second) < 0) {
return merge(first, onePassSort(list.subList(1, list.size())));
} else {
return merge(second, onePassSort(merge(first, list.subList(2, list.size()))));
}
}
}
public static <T> List<T> merge(T head, List<T> tail) {
List<T> result = new ArrayList<>();
result.add(head);
result.addAll(tail);
return result;
}
公共静态最终列表functionalBubbleSort(列表列表){
对于(int i=0;i
我找到了一个合理的方法:
@SuppressWarnings(“未选中”)
公共静态最终列表declarativeBubbleSort(最终列表){
列表结果=新的ArrayList(列表);
int len=result.size();
功能消费者=
重复->长度->IntStream.range(0,长度)
.filter(i->IntStream.range(0,len-i-1)
.filter(j->result.get(j+1).比较(result.get(j))<0)
.mapToObj(j->{
T swap=结果。移除(j+1);
结果。添加(j,交换);
收益互换;
}).count()>0)
.max().ifPresent(IntConsumer.class.cast(recur.apply(Function.class.cast(recur)));
consumer.apply(Function.class.cast(consumer)).accept(len);
返回结果;
}
我知道我仍然有点急迫,但对于这种类型,我发现很难用Java完全声明性地完成,也很难不影响性能
如果你想成为平行的,那么:
@SuppressWarnings(“未选中”)
公共静态最终列表声明性ParallelBubbleSort(最终列表){
列表结果=新的ArrayList(列表);
int len=result.size();
功能消费者=
重复->长度->IntStream.range(0,长度)
.filter(i->IntStream.range(0,len-i-1)
.filter(j->result.get(j+1).比较(result.get(j))<0)
.parallel()
.mapToObj(j->{
已同步(结果){
T swap=结果。移除(j+1);
结果。添加(j,交换);
收益互换;
}
}).count()>0)
.max().ifPresent(IntConsumer.class.cast(recur.apply(Function.class.cast(recur)));
consumer.apply(Function.class.cast(consumer)).accept(len);
返回结果;
}
我能想到的最短的方法就是跟随。其中listForBubbleSort是输入,bubbleSorted是输出
List listForBubbleSort=Arrays.asList(5,4,3,7,6,9,11,10,21);
最终列表copiedList=新的ArrayList(listForBubbleSort);
copiedList.add(Integer.MAX_值);
最终列表bubbleSorted=新ArrayList();
copiedList.stream().reduce((c,e)->{
if(c
我仍然觉得,如果我们可以创建一个定制收集器,并将收集器传递给流的收集器,那将是非常棒的。就像我们将collect(toList())
传递给流一样。但仍在学习Java8,因此需要更多的时间来创建相同的。
如果有人已经为相同的收集器创建了自定义收集器,请共享。使用Java 8 api的简化版本:
公共静态int[]bubbleSort(int[]array){
双消费者swapValueIf=(a,j)->{
如果(a[j]>a[j+1]){
内部温度=a[j];
数组[j]=a[j+1];
阵列[j+1]=温度;
}
};
IntStream.range(0,array.length-1)
.forEach(i->IntStream.range(0,array.length-1)
.forEach(j->swapValueIf.accept(数组,j));
返回数组;
}
具有两个