亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

怎么在Java中使用函數實現二維數組的遍歷

發布時間:2023-05-08 11:54:46 來源:億速云 閱讀:132 作者:zzz 欄目:編程語言

這篇“怎么在Java中使用函數實現二維數組的遍歷”文章的知識點大部分人都不太理解,所以小編給大家總結了以下內容,內容詳細,步驟清晰,具有一定的借鑒價值,希望大家閱讀完這篇文章能有所收獲,下面我們一起來看看這篇“怎么在Java中使用函數實現二維數組的遍歷”文章吧。

前言

對于數組遍歷,基本上每個開發者都寫過,遍歷本身沒什么好說的,但是當我們在遍歷的過程中,有一些復雜的業務邏輯時,將會發現代碼的層級會逐漸加深

如一個簡單的case,將一個二維數組中的偶數找出來,保存到一個列表中

二維數組遍歷,每個元素判斷下是否為偶數,很容易就可以寫出來,如:

public void getEven() {
    int[][] cells = new int[][]{{1, 2, 3, 4}, {11, 12, 13, 14}, {21, 22, 23, 24}};
    List<Integer> ans = new ArrayList<>();
    for (int i = 0; i < cells.length; i ++) {
        for (int j = 0; j < cells[0].length; j++) {
            if ((cells[i][j] & 1) == 0) {
                ans.add(cells[i][j]);
            }
        }
    }
    System.out.println(ans);
}

上面這個實現沒啥問題,但是這個代碼的深度很容易就有三層了;當上面這個if中如果再有其他的判定條件,那么這個代碼層級很容易增加了;二維數組還好,如果是三維數組,一個遍歷就是三層;再加點邏輯,四層、五層不也是分分鐘的事情么

那么問題來了,代碼層級變多之后會有什么問題呢?

只要代碼能跑,又能有什么問題呢?!

1. 函數方法消減代碼層級

由于多維數組的遍歷層級天然就很深,那么有辦法進行消減么?

要解決這個問題,關鍵是要抓住重點,遍歷的重點是什么?獲取每個元素的坐標!那么我們可以怎么辦?

定義一個函數方法,輸入的就是函數坐標,在這個函數體中執行我們的遍歷邏輯即可

基于上面這個思路,相信我們可以很容易寫一個二維的數組遍歷通用方法

public static void scan(int maxX, int maxY, BiConsumer<Integer, Integer> consumer) {
    for (int i = 0; i < maxX; i++) {
        for (int j = 0; j < maxY; j++) {
            consumer.accept(i, j);
        }
    }
}

主要上面的實現,函數方法直接使用了JDK默認提供的BiConsumer,兩個傳參,都是int 數組下表;無返回值

那么上面這個怎么用呢?

同樣是上面的例子,改一下之后,如:

public void getEven() {
    int[][] cells = new int[][]{{1, 2, 3, 4}, {11, 12, 13, 14}, {21, 22, 23, 24}};
    List<Integer> ans = new ArrayList<>();
    scan(cells.length, cells[0].length, (i, j) -> {
        if ((cells[i][j] & 1) == 0) {
            ans.add(cells[i][j]);
        }
    });
    System.out.println(ans);
}

相比于前面的,貌似也就少了一層而已,好像也沒什么了不起的

但是,當數組變為三維、四維、無維時,這個改動的寫法層級都不會變哦

2. 遍歷中return支持

前面的實現對于正常的遍歷沒啥問題;但是當我們在遍歷過程中,遇到某個條件直接返回,能支持么?

如一個遍歷二維數組,我們希望判斷其中是否有偶數,那么可以怎么整?

仔細琢磨一下我們的scan方法,希望可以支持return,主要的問題點就是這個函數方法執行之后,我該怎么知道是繼續循環還是直接return呢?

很容易想到的就是執行邏輯中,添加一個額外的返回值,用于標記是否中斷循環直接返回

基于此思路,我們可以實現一個簡單的demo版本

定義一個函數方法,接受循環的下標 + 返回值

@FunctionalInterface
public interface ScanProcess<T> {
    ImmutablePair<Boolean, T> accept(int i, int j);
}

循環通用方法就可以相應的改成:

public static <T> T scanReturn(int x, int y, ScanProcess<T> func) {
    for (int i = 0; i < x; i++) {
        for (int j = 0; j < y; j++) {
            ImmutablePair<Boolean, T> ans = func.accept(i, j);
            if (ans != null && ans.left) {
                return ans.right;
            }
        }
    }
    return null;
}

基于上面這種思路,我們的實際使用姿勢如下:

@Test
public void getEven() {
    int[][] cells = new int[][]{{1, 2, 3, 4}, {11, 12, 13, 14}, {21, 22, 23, 24}};
    List<Integer> ans = new ArrayList<>();
    scanReturn(cells.length, cells[0].length, (i, j) -> {
        if ((cells[i][j] & 1) == 0) {
            return ImmutablePair.of(true, i + "_" + j);
        }
        return ImmutablePair.of(false, null);
    });
    System.out.println(ans);
}

上面這個實現可滿足我們的需求,唯一有個別扭的地方就是返回,總有點不太優雅;那么除了這種方式之外,還有其他的方式么?

既然考慮了返回值,那么再考慮一下傳參呢?通過一個定義的參數來裝在是否中斷以及返回結果,是否可行呢?

基于這個思路,我們可以先定義一個參數包裝類:

public static class Ans<T> {
    private T ans;
    private boolean tag = false;

    public Ans<T> setAns(T ans) {
        tag = true;
        this.ans = ans;
        return this;
    }

    public T getAns() {
        return ans;
    }
}

public interface ScanFunc<T> {
    void accept(int i, int j, Ans<T> ans)
}

我們希望通過Ans這個類來記錄循環結果,其中tag=true,則表示不用繼續循環了,直接返回ans結果吧

與之對應的方法改造及實例如下:

public static <T> T scanReturn(int x, int y, ScanFunc<T> func) {
    Ans<T> ans = new Ans<>();
    for (int i = 0; i < x; i++) {
        for (int j = 0; j < y; j++) {
            func.accept(i, j, ans);
            if (ans.tag) {
                return ans.ans;
            }
        }
    }
    return null;
}
public void getEven() {
    int[][] cells = new int[][]{{1, 2, 3, 4}, {11, 12, 13, 14}, {21, 22, 23, 24}};
    String ans = scanReturn(cells.length, cells[0].length, (i, j, a) -> {
        if ((cells[i][j] & 1) == 0) {
            a.setAns(i + "_" + j);
        }
    });
    System.out.println(ans);
}

這樣看起來就比前面的要好一點了

實際跑一下,看下輸出是否和我們預期的一致;

怎么在Java中使用函數實現二維數組的遍歷

以上就是關于“怎么在Java中使用函數實現二維數組的遍歷”這篇文章的內容,相信大家都有了一定的了解,希望小編分享的內容對大家有幫助,若想了解更多相關的知識內容,請關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

宿松县| 彭山县| 大庆市| 河西区| 娄烦县| 峨山| 漾濞| 普宁市| 通榆县| 岑巩县| 巢湖市| 普格县| 仪征市| 揭东县| 洛隆县| 山东| 饶河县| 盐亭县| 德惠市| 广汉市| 姚安县| 垫江县| 晋宁县| 斗六市| 英吉沙县| 正宁县| 东源县| 永州市| 固镇县| 建昌县| 平山县| 巩留县| 威远县| 满城县| 西乡县| 婺源县| 清原| 宜章县| 兴隆县| 阳江市| 罗平县|