日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

java8 函数式编程_如何使用Java 8函数式编程生成字母序列

發布時間:2023/12/3 java 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java8 函数式编程_如何使用Java 8函数式编程生成字母序列 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

java8 函數式編程

我偶然發現了用戶“ 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

    java8 函數式編程

    總結

    以上是生活随笔為你收集整理的java8 函数式编程_如何使用Java 8函数式编程生成字母序列的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。