真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

Java8中怎么實(shí)現(xiàn)函數(shù)式編程

這期內(nèi)容當(dāng)中小編將會(huì)給大家?guī)?lái)有關(guān)Java 8中怎么實(shí)現(xiàn)函數(shù)式編程,文章內(nèi)容豐富且以專業(yè)的角度為大家分析和敘述,閱讀完這篇文章希望大家可以有所收獲。

目前創(chuàng)新互聯(lián)公司已為1000多家的企業(yè)提供了網(wǎng)站建設(shè)、域名、網(wǎng)絡(luò)空間、網(wǎng)站托管運(yùn)營(yíng)、企業(yè)網(wǎng)站設(shè)計(jì)、阜康網(wǎng)站維護(hù)等服務(wù),公司將堅(jiān)持客戶導(dǎo)向、應(yīng)用為本的策略,正道將秉承"和諧、參與、激情"的文化,與客戶和合作伙伴齊心協(xié)力一起成長(zhǎng),共同發(fā)展。

我被 Stack Overflow 上網(wǎng)友“mip”提的一個(gè)有趣的問(wèn)題給難住了。該問(wèn)題是:

1
2
3
我正在尋找一種生成下列字母序列的方式:
 
A, B, C, ..., Z, AA, AB, AC, ..., ZZ.

大家應(yīng)該能夠很快認(rèn)出這是 Excel spreadsheet 的頭部,準(zhǔn)確的樣子如下:
Java 8中怎么實(shí)現(xiàn)函數(shù)式編程

到現(xiàn)在為止,沒有一個(gè)答案是使用 Java 8 的函數(shù)式編程實(shí)現(xiàn)的,因此我接受此挑戰(zhàn)。我將使用 jOOλ,因?yàn)?Java 8 的 Stream API 提供的功能不足以完成該任務(wù)(我承認(rèn)我錯(cuò)了——非常感謝 Sebastian 對(duì)這個(gè)問(wèn)題的有趣解答)。

首先,我們用函數(shù)的方式分解這個(gè)算法。我們所需要的組件有:

1、一個(gè)(可重復(fù))的字母表。

2、一個(gè)上界,例如想生成多少個(gè)字母。如要求生成序列ZZ,那上界就是2。

3、一種將字母表中的字母與先前生成的字母聯(lián)合成一個(gè)笛卡爾積(cartesian product)的方法。

讓我們看一下代碼:

1、生成字母表

我們可以這樣寫入字母表,如:

1
List alphabet = Arrays.asList("A", "B", ..., "Z");

但這很差勁。我們使用 jOOλ 代替:

1
2
3
4
List alphabet = Seq
    .rangeClosed('A', 'Z')
    .map(Object::toString)
    .toList();

上面的代碼生成從字符 A 到 Z 的封閉區(qū)間(Java-8-Stream-speak 是包含上邊界的),然后將字符映射成字符串,***將其轉(zhuǎn)換為列表。

目前為止,一切都很好?,F(xiàn)在:

2、使用上邊界:

要求的字符序列包括:

1
A .. Z, AA, AB, .. ZZ

但是我們應(yīng)該很容易想到擴(kuò)展該需求,能生成如下字符序列,或者更多:

1
A .. Z, AA, AB, .. ZZ, AAA, AAB, .. ZZZ

因此,我們將再次使用 rangeClosed():

1
2
3
4
// 1 = A .. Z, 2 = AA .. ZZ, 3 = AAA .. ZZZ
Seq.rangeClosed(1, 2)
   .flatMap(length -> ...)
   .forEach(System.out::println);

這種方法是為范圍[1..2]中每個(gè)長(zhǎng)度生成一個(gè)單獨(dú)的流,然后再將這些流合并到一個(gè)流中。flatMap() 的本質(zhì)與命令式編程(imperative programming)中的嵌套循環(huán)類似。

3、合并字母到一個(gè)笛卡爾積中

這是最棘手的部分:我們需要合并字符及出現(xiàn)的次數(shù)。因此,我們將使用如下的流:

1
2
3
4
5
Seq.rangeClosed(1, length - 1)
   .foldLeft(Seq.seq(alphabet), (s, i) ->
       s.crossJoin(Seq.seq(alphabet))
        .map(t -> t.v1 + t.v2))
    );

我們?cè)俅问褂?rangeClosed() 來(lái)生成范圍 [1 .. length-1] 的值。foldLeft() 與 reduce() 基本一致,區(qū)別在于 foldLeft() 保證在流中的順序是從“左至右”的,不需要 fold 函數(shù)來(lái)關(guān)聯(lián)。

另一方面,這是一個(gè)共容易懂的詞匯:foldLeft()  僅代表一條循環(huán)的命令。循環(huán)的“起源”(即循環(huán)的初始化值)是一個(gè)完整的字母表(Seq.seq(alphabet))。現(xiàn)在,在范圍 [1..length-1]  中的值生成一個(gè)笛卡爾積(crossJoin()),產(chǎn)生一個(gè)新的字母表,然后我們將每個(gè)合并的字母再組成一個(gè)單獨(dú)的字符串(t.v1 與 t.v2)。

這就是整個(gè)過(guò)程。

將上面的內(nèi)容合并到一起

下面是一個(gè)簡(jiǎn)單的打印 A .. Z, AA .. ZZ, AAA .. ZZZ 到控制臺(tái)的程序:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import org.jooq.lambda.Seq;
public class Test {
    public static void main(String[] args) {
        int max = 3;
        List 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);
    }
}

聲明

對(duì)于這個(gè)問(wèn)題,這確實(shí)不是***的算法。在Stack Overflow,有一個(gè)匿名用戶給出了一種***實(shí)現(xiàn)方法。

1
2
3
4
5
6
7
8
9
10
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);
}

上述就是小編為大家分享的Java 8中怎么實(shí)現(xiàn)函數(shù)式編程了,如果剛好有類似的疑惑,不妨參照上述分析進(jìn)行理解。如果想知道更多相關(guān)知識(shí),歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道。


文章標(biāo)題:Java8中怎么實(shí)現(xiàn)函數(shù)式編程
當(dāng)前路徑:http://weahome.cn/article/ipejcs.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部