如何在 Java 中删除重复的列表遍历

Posted

技术标签:

【中文标题】如何在 Java 中删除重复的列表遍历【英文标题】:How to remove a duplicated list traversal in 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
    

【问题讨论】:

【参考方案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
    

【讨论】:

以上是关于如何在 Java 中删除重复的列表遍历的主要内容,如果未能解决你的问题,请参考以下文章

如何删除列表视图中重复的联系人?

如何从Java列表中删除重复项

Python如何删除列表中的重复元素?

如何遍历存储在数组列表中的对象[重复]

如何从java arraylist中删除重复的对象[重复]

uniapp遍历出来的列表点关注图片都改变,怎么解决