java8 函数式编程_如何使用Java 8函数式编程生成字母序列
java8 函數式編程
我偶然發現了用戶“ mip”一個有趣的堆棧溢出問題 。 問題是:
我正在尋找一種生成字母序列的方法:
A, B, C, ..., Z, AA, AB, AC, ..., ZZ.可以很快將其識別為Excel電子表格的標題,它確實做到了:
到目前為止,沒有答案使用任何Java 8函數式編程,我認為這是一個挑戰。 我們將使用jOOλ ,因為Java 8 Stream API不能為該任務提供足夠的功能 。
但是首先,讓我們以功能性方式分解算法。 我們需要的是以下組件:
讓我們看一些代碼:
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
java8 函數式編程
總結
以上是生活随笔為你收集整理的java8 函数式编程_如何使用Java 8函数式编程生成字母序列的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 采购备案表(采购备案单)
- 下一篇: 查看linux防火墙状态(查看linux