在Java中填充布尔数组

lor*_*lor 72 java arrays

作为一个相当绿色的Java编码器,我为自己设置了一个尝试编写简单文本冒险的巨大挑战.不出所料,我已经遇到了困难!

我正在尝试为我的Location类提供一个属性来存储它包含的出口.我为此使用了一个布尔数组,基本上保存表示每个出口的true/false值.我并不完全相信

a)这是最有效的方法

b)我正在使用正确的代码来填充数组.

我会很感激任何和所有的反馈,即使它是一个完整的代码超载!

目前,在实例化一个Location时,我会生成一个String,我将其发送到setExits方法:

    String e = "N S U";
    secretRoom.setExits(e);
Run Code Online (Sandbox Code Playgroud)

在Location类中,setExits如下所示:

public void setExits(String e) {
    if (e.contains("N"))
        bexits[0] = true;
    else if (e.contains("W"))
        bexits[1] = true;
    else if (e.contains("S"))
        bexits[2] = true;
    else if (e.contains("E"))
        bexits[3] = true;
    else if (e.contains("U"))
        bexits[4] = true;
    else if (e.contains("D"))
        bexits[5] = true;
}
Run Code Online (Sandbox Code Playgroud)

我会说实话,我认为这看起来特别笨重,但我想不出另一种方法.我现在还不完全确定如何编写getExits方法......

欢迎任何帮助!

gex*_*ide 127

最有效最富有表现力的方式如下:

使用enums作为退出并使用a EnumSet来存储它们.EnumSet是一个有效的Set实现,它使用位字段来表示枚举常量.

以下是如何做到这一点:

public enum Exit { North, West, South, East, Up, Down; }

EnumSet<Exit> set = EnumSet.noneOf(Exit.class); // An empty set.

// Now you can simply add or remove exits, everything will be stored compactly

set.add(Exit.North); // Add exit
set.contains(Exit.West); // Test if an exit is present
set.remove(Exit.South); //Remove an exit
Run Code Online (Sandbox Code Playgroud)

枚举设置将所有出口存储在一个long内部,因此您的代码具有表现力,快速,并节省大量内存.

  • 我喜欢这个答案的简单!为了使代码更具可读性,我还要使每个枚举方向都是全名,而不是第一个字母.即`public enum Exit {North,West,South,East,Up,Down; }` (3认同)
  • @zamnuts如果Enum中有太多元素,EnumSet的实现将使用JumboEnumSet.请参阅http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java/util/JumboEnumSet.java#JumboEnumSet (2认同)

Ros*_*rew 29

你有没有理由用Strings 做这个并没有传入booleans,即

public void setExits(boolean N, boolean E, boolean S, boolean W, boolean U, boolean D) 
Run Code Online (Sandbox Code Playgroud)

或者有制定者

public void setNorthOpen(boolean open)
{
  bexits[4] = open;
}
Run Code Online (Sandbox Code Playgroud)

其次,为什么你将出口存储为一个布尔数组,它是一个小的有限集,为什么不呢

boolean N,S,E,W,U,D;
Run Code Online (Sandbox Code Playgroud)

那时你不需要跟踪每个方向的数组中的数字.

这是一个正确的答案(如果不是像@gexicide那样完全最优)但我完全鼓励任何人在这里查看其他答案,以便以不同的方式了解如何在Java中完成任务.

备查

有效的代码属于Code Review,而不是Stack Overflow.虽然正如@kajacx指出的那样,这段代码实际上不应该起作用.

  • setExits(false,true,false,true)读起来会很糟糕,另一个答案中建议的枚举变体就是优越的. (14认同)
  • 另外,感谢有关Code Review的观点 - 我不知道这一点,但请记住以备将来参考. (2认同)

kaj*_*acx 15

好的,首先,你的setExits()方法不会按预期工作,链接if-elseif将最大限度地执行1个代码分支,例如:

if (e.contains("N"))
    bexits[0] = true;
else if (e.contains("W"))
    bexits[1] = true;
Run Code Online (Sandbox Code Playgroud)

即使e同时包含NW,只bexits[0]将被设置.此方法也只会添加退出(例如,调用setExits("")不会删除任何现有的退出.

我会将该方法更改为:

bexits[0] = e.contains("N");
bexits[1] = e.contains("W");
...
Run Code Online (Sandbox Code Playgroud)

此外,我绝对不会记得北方在索引0上,西方在1上,...所以通常的做法是使用最终的静态常量命名索引:

public static final int NORTH = 0;
public static final int WEST = 1;
...
Run Code Online (Sandbox Code Playgroud)

然后你可以用你的setExits方法写:

bexits[NORTH] = e.contains("N");
bexits[WEST] = e.contains("W");
...
Run Code Online (Sandbox Code Playgroud)

(更容易读)

最后,如果您希望代码更加精心安排,您可以创建一个Exits表示可用出口的类,并由布尔数组支持.然后在创建String的地方,您可以创建此类,并自己保存,然后生成然后解析字符串.

编辑:

作为@gexicide的答案,有一个非常方便的类EnumSet,可能比bollean数组更好地表示出口.

  • `public static final int`感觉像Java 1.4,并且被替换为枚举 (8认同)

Tim*_*m B 9

EnumSet在对方的回答是做到这一点的最好办法,我只是想,虽然加上一句话,就是为将来当你开始就在你是否可以移动但如果你正在向不看.

EnumSet你一样EnumMap.

如果你定义一个Room类/接口,那么你可以在Room类中

Map<Direction, Room> exits = new EnumMap<>(Direction.class);
Run Code Online (Sandbox Code Playgroud)

您现在可以将链接添加到地图中,如下所示:

exits.put(Direction.NORTH, theRoomNorthOfMe);
Run Code Online (Sandbox Code Playgroud)

然后你的代码在房间之间移动可以是非常通用的:

Room destination=currentRoom.getExit(directionMoved);

if (destination == null) {
    // Cannot move that way
} else {
    // Handle move to destination
}
Run Code Online (Sandbox Code Playgroud)


nie*_*ame 7

我将创建一个Exit枚举,并在location类上设置一个Exit对象列表.

所以它会是这样的:

public enum Exit { N, S, E, W, U, D }

List<Exit> exits = parseExits(String exitString);
location.setExits(exits);
Run Code Online (Sandbox Code Playgroud)


Rob*_*sen 6

鉴于您的代码是什么样的,这是我可以提出的最具可读性的实现:

public class Exits {
    private static final char[] DIRECTIONS = "NSEWUD".toCharArray();

    public static void main(String... args) {
        String input = "N S E";
        boolean[] exits = new boolean[DIRECTIONS.length];

        for(int i = 0; i< exits.length; i++) {
            if (input.indexOf(DIRECTIONS[i]) >= 0) {
                exits[i] = true;
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

话虽如此,有一些更清洁的解决方案可能.我个人会用枚举和一个EnumSet.

顺便说一句,您的原始代码是不正确的,因为它将数组中的大多数值设置为true.