【问题标题】:How to remove a duplicated list traversal in Java如何在 Java 中删除重复的列表遍历
【发布时间】:2015-07-12 05:40:42
【问题描述】:

我正在创建一个单人纸牌游戏,它将卡片存储在 arraylist 中。 我想创建两种方法来检查玩家的移动和播放。

一个布尔函数,它通过 ArrayList 并检查是否有任何可能的移动。如果有可能,此方法返回 true。

第二个动作。它还通过 ArrayList 并检查是否有任何可能的移动,进行移动并停止工作。为了阻止它,我使用了 return true。但我认为这不是好方法。

而且两个函数很相似,代码是重复的。如何解决? 这个看起来是任何可能移动的方法应该返回布尔值还是可以移动的两个卡片数量(a和b)?

public boolean makeMove() {
    int a = 0; //index of one card
    int b; //index of second card
    for (b = getSize() - 1; b > 0; b--) {
        for (a = 0; a < b; a++) {
            if (isCorrectMove(a, b)) {
                swap(a, b); //makes move
                return true; //exit after move
            }
        }
    }
    return false; //if there was no move
}

public boolean isPossibleAnyMove() {int a = 0; //index of one card
        int b; //index of second card
        for (b = getSize() - 1; b > 0; b--) {
            for (a = 0; a < b; a++) {
                if (isCorrectMove(a, b)) {
                    return true; //returns true if there was a move
                }
            }
        }
        return false; //if there was no move
    }

【问题讨论】:

    标签: java oop arraylist


    【解决方案1】:

    你可以创建一个函数来找到第一个正确的移动;此函数将返回一个对象,其中包含正确移动的值 ab,如果没有正确移动,则返回 null

    private static class Move {
    
        int a, b;
    
        Move(int a, int b) {
            this.a = a;
            this.b = b;
        }
    
    }
    
    private Move findFirstCorrectMove() {
        int a = 0; //index of one card
        int b; //index of second card
        for (b = getSize() - 1; b > 0; b--) {
            for (a = 0; a < b; a++) {
                if (isCorrectMove(a, b)) {
                    return new Move(a,b);
                }
            }
        }
        return null; //if there was no move
    }
    
    public boolean makeMove() {
        Move move = findFirstCorrectMove();
        if (move != null) {
            swap(move.a, move.b);
            return true;
        }
        return false;
    }
    
    public boolean isPossibleAnyMove() {
        return findFirstCorrectMove() != null;
    }
    

    当然,您可以简单地使用 int[] 数组,而不是创建新的 Move 类。


    您还可以使用策略模式来处理移动。我希望代码中的一些 java 8 特性不会打扰到您:

    @FunctionalInterface
    interface MoveConsumer {
        void acceptMove(int a, int b);
    }
    
    private boolean findFirstCorrectMove(MoveConsumer moveConsumer) {
        int a = 0; //index of one card
        int b; //index of second card
        for (b = getSize() - 1; b > 0; b--) {
            for (a = 0; a < b; a++) {
                if (isCorrectMove(a, b)) {
                    moveConsumer.acceptMove(a, b);
                    return true;
                }
            }
        }
        return false; //if there was no move
    }
    
    public boolean makeMove() {
        return findFirstCorrectMove(this::swap); // assuming here that swap is non-static
    }
    
    public boolean isPossibleAnyMove() {
        return findFirstCorrectMove((a, b) -> {});
    }
    

    【讨论】:

    • 哇,这几乎就是我的建议,尽管你比我强。我会删除我的答案。
    • 哈哈,看来我们都写了同一个答案。你打败了我。
    • 您也可以考虑使用 Java 的 8 Optional 或 Google Guava Optional 作为 findCorrectMove 方法,而不是使用 null。
    • 好的。非常感谢。也可能是这里使用的策略设计模式?
    • 很好,但是这种策略模式是如何工作的?
    【解决方案2】:
    public boolean someName(boolean shouldSwap) {
        int a = 0; //index of one card
        int b; //index of second card
        for (b = getSize() - 1; b > 0; b--) {
            for (a = 0; a < b; a++) {
                if (isCorrectMove(a, b)) {
                    if (shouldSwap)
                        swap(a, b); //makes move
                    return true; //exit after move
                }
            }
        }
        return false; //if there was no move
    }
    

    如果交换是唯一的区别,那么这是一种将这两个功能组合在一起的可能方法......

    【讨论】:

    • 谢谢,但是面向对象的编程方法是否正确?这个功能是不是做的太多了?
    • 是的,在我看来这确实破坏了凝聚力。
    【解决方案3】:

    您可以创建一个使用布尔值来控制行为的函数。

    public boolean CheckOrmakeMove(boolean swapBool) {
            int a = 0; //index of one card
            int b; //index of second card
            for (b = getSize() - 1; b > 0; b--) {
                for (a = 0; a < b; a++) {
                    if (isCorrectMove(a, b)) {
                        if(swapBool)
                        swap(a, b); //makes move
                        return true; //exit after move
                    }
                }
            }
            return false; //if there was no move
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-11-24
      • 1970-01-01
      • 2016-03-31
      • 1970-01-01
      • 2013-08-05
      • 2018-06-27
      • 2020-05-15
      • 2019-10-16
      相关资源
      最近更新 更多