如何使用Java 8函数式编程生成字母序列
我偶然发现了用户“ mip”一个有趣的堆栈溢出问题 。 问题是:
我正在寻找一种生成字母序列的方法:
A, B, C, ..., Z, AA, AB, AC, ..., ZZ.
可以很快将其识别为Excel电子表格的标题,正是这样:
到目前为止,没有答案使用任何Java 8函数式编程,我认为这是一个挑战。 我们将使用jOOλ ,因为Java 8 Stream API不能为该任务提供足够的功能 。
但首先,让我们以功能性方式分解算法。 我们需要的是以下组件:
- 字母的(可再现)表示
- 上限,即我们要产生多少个字母。 请求的序列转到
ZZ
,这意味着上限为2 - 一种将笛卡尔积中的每个字母与先前生成的组合字母进行组合的方法
让我们看一些代码:
1.生成字母
我们可以这样写字母:
List<String> alphabet = Arrays.asList("A", "B", ..., "Z");
但这很la脚。 让我们使用jOOλ生成它:
List<String> alphabet = Seq.rangeClosed('A', 'Z').map(Object::toString).toList();
上面的代码生成A
和Z
之间的字符的“封闭”范围( 对于上限为包含范围的范围,使用Java-8流表示 ),将字符映射为字符串并将其收集到列表中。
到目前为止,一切都很好。 现在:
2.使用上限
请求的字符序列包括:
A .. Z, AA, AB, .. ZZ
但是,我们可以轻易地想象将这一要求扩展到产生以下甚至更多的需求。
A .. Z, AA, AB, .. ZZ, AAA, AAB, .. ZZZ
为此,我们将再次使用rangeClosed()
:
// 1 = A .. Z, 2 = AA .. ZZ, 3 = AAA .. ZZZ
Seq.rangeClosed(1, 2).flatMap(length -> ...).forEach(System.out::println);
这里的想法是为[1 .. 2]
范围内的每个单独长度生成一个新的流,并将这些流平整为一个单个流。 flatMap()
本质上与命令式编程中的嵌套循环相同。
3.将字母组合成笛卡尔积
这是最棘手的部分:我们需要将每个字母与每个字母的length
进行组合。 为此,我们将使用以下流:
Seq.rangeClosed(1, length - 1).foldLeft(Seq.seq(alphabet), (s, i) -> s.crossJoin(Seq.seq(alphabet)).map(t -> t.v1 + t.v2)));
我们再次使用rangeClosed()
来产生[1 .. length-1]
范围内的值。 foldLeft()
与reduce()
相同,除了foldLeft()
可以在流中从“左向右”移动,而无需折叠函数具有关联性。 ew。
换句话说,更容易理解的词是: foldLeft()
只是命令性循环。 循环的“种子”,即循环的初始值,是完整的字母( Seq.seq(alphabet)
)。 现在,对于[1 .. length-1]
范围内的每个值,我们产生一个笛卡尔积( crossJoin()
)到到目前为止“折叠”的一个字母和一个新的字母之间,并将每个组合连接成一个新的字符串( t.v1
和t.v2
)。
而已!
结合一切
以下简单程序将A .. Z, AA .. ZZ, AAA .. ZZZ
所有值打印到控制台:
import java.util.List;import org.jooq.lambda.Seq;public class Test {public static void main(String[] args) {int max = 3;List<String> alphabet = Seq.rangeClosed('A', 'Z').map(Object::toString).toList();Seq.rangeClosed(1, max).flatMap(length ->Seq.rangeClosed(1, length - 1).foldLeft(Seq.seq(alphabet), (s, i) -> s.crossJoin(Seq.seq(alphabet)).map(t -> t.v1 + t.v2))).forEach(System.out::println);}
}
免责声明
对于这种特殊情况,这当然不是最佳算法。 一名不知名的用户在Stack Overflow上给出了最好的实现之一 :
import static java.lang.Math.*;private static String getString(int n) {char[] buf = new char[(int) floor(log(25 * (n + 1)) / log(26))];for (int i = buf.length - 1; i >= 0; i--) {n--;buf[i] = (char) ('A' + n % 26);n /= 26;}return new String(buf);
}
不必说后者比以前的功能算法快得多。
翻译自: https://www.javacodegeeks.com/2015/09/how-to-use-java-8-functional-programming-to-generate-an-alphabetic-sequence-2.html
如何使用Java 8函数式编程生成字母序列相关推荐
- java8 函数式编程_如何使用Java 8函数式编程生成字母序列
java8 函数式编程 我偶然发现了用户" mip"一个有趣的堆栈溢出问题 . 问题是: 我正在寻找一种生成字母序列的方法: A, B, C, ..., Z, AA, AB, AC ...
- 阅读笔记–Java 8函数式编程,建议看书,作者高屋建瓴
阅读笔记–Java 8函数式编程 书籍代码 为什么需要再次修改Java 1996年1月,Java1.0发布,商业发展需要更复杂的应用,跑在功能强大的多核CPU机器上.带有高效运行时编译器的Java虚拟 ...
- Java 代码写的又臭又长,还不会用 Java Stream 函数式编程?
点击上方"猿芯",选择"设为星标" 后台回复"1024",有份惊喜送给面试的你 原文 https://www.cnblogs.com/Car ...
- Java 8 函数式编程学习笔记
Java 8 函数式编程学习笔记 @(JAVASE)[java8, 函数式编程, lambda] Java 8 函数式编程学习笔记 参考内容 Java 8中重要的函数接口 扩展函数接口 常用的流操作 ...
- 【Java】函数式编程学习笔记——Stream流
学习视频:https://www.bilibili.com/video/BV1Gh41187uR?p=1 (1)[Java]函数式编程学习笔记--Lambda表达式 (2)[Java]函数式编程学习笔 ...
- 深度探秘 Java 8 函数式编程(下)
函数式编程的益处 更精练的代码 函数编程的一大益处,是用更精练的代码表达常用数据处理模式.函数接口能够轻易地实现模板方法模式,只要将不确定的业务逻辑抽象成函数接口,然后传入不同的lambda表达式即可 ...
- java supplier_Java 函数式编程
前些年 Scala 大肆流行,打出来 Java 颠覆者的旗号,究其底气来源,无非是函数式和面向对象的"完美结合",各式各样的"语法糖",但其过高的学习门槛,又给 ...
- Java 8th 函数式编程:lambda 表达式
Lambda 表达式是 java 8th 给我们带来的几个重量级新特性之一,借用 lambda 表达式可以让我们的程序设计更加简洁.最近新的项目摒弃了 6th 版本,全面基于 8th 进行开发,本文将 ...
- 【Java】函数式编程
1 函数式接口 1.1 概念 函数式接口是有且仅有一个抽象方法的接口,可以包括静态和默认方法. @FunctionalInterface:加上注解,检测是否的函数式接口 @FunctionalInte ...
最新文章
- Java并发之同步的产生及解决
- php5.4环境升级,CentOS环境中编译升级PHP至5.4版本记录
- docker 提交自定义镜像
- xadmin获取mysql_Django+Xadmin构建项目的方法步骤
- 《算法基础》——3.9 总结
- 追赶法源程序c语言,追赶法求三对角线方程组程序设计.doc
- GNS3安装和使用教程
- 通达信在linux下界面难看,通达信看盘设置小技巧,主力也在用的设置技巧
- 长整数转化成16进制字符串
- Github Actions实现自定义编译OpenWRT固件和第三方插件
- 阿里Java后端开发面经,面试官都替我感到绝望
- 【转】似大地水准面精化
- Docker自定义镜像上传阿里云
- Dashed hopes 破灭的希望,新兴国家的出路在何方?经济学人精读
- 618这款秒杀神器Python介绍给你,低调使用哦,因为太赞了
- 【Verilog】CRC校验码生成器原理及verilog实现
- VARCHART XGantt系列教程:如何利用颜色来丰富甘特图智能
- 基于EF框架的数据库操作方法
- NVIDIA Jetson TK1学习与开发(十一):TK1新装ubuntu如何修改用户密码和root密码
- 清理bib文件(删除重复项,仅保留tex中引用的条目)
热门文章
- 小二,先来两桂花豆沙包!
- 高效的SQLSERVER分页查询
- java面向对象高级分层实例_实体类
- 2015蓝桥杯省赛---java---A---3(九数分三组)
- ES报错:Connection reset by peer 解决经历
- layUI 日期组件单独使用 并且放大
- tomcat(19)Manager应用程序的servlet类
- apache ignite_Kubernetes集群上的Apache Ignite和Spring第2部分:Kubernetes部署
- java源文件编译成jar_从源文件和JAR文件构建Java代码模型
- java面试题2014_Java生态系统– 2014年我的5大亮点