[英]Fastest way in Java to find a specific enum based on a lookup of two integers
我有以下三个枚举:
玩家类型
public enum PlayerType {
NONE (' '),
BLACK ('b'),
WHITE ('w');
private final char _symbol;
PlayerType(char symbol) {
_symbol = symbol;
}
public char symbol() { return _symbol; }
}
件型
public enum PieceType {
NONE (' '),
PAWN ('p'),
KNIGHT ('n'),
BISHOP ('b'),
ROOK ('r'),
QUEEN ('q'),
KING ('k');
private final char _symbol;
PieceType(char symbol) {
_symbol = symbol;
}
public char symbol() { return _symbol; }
}
播放器
public enum PlayerPiece {
NONE (PlayerType.NONE, PieceType.NONE),
BLACK_PAWN (PlayerType.BLACK, PieceType.PAWN),
BLACK_KNIGHT (PlayerType.BLACK, PieceType.KNIGHT),
BLACK_BISHOP (PlayerType.BLACK, PieceType.BISHOP),
BLACK_ROOK (PlayerType.BLACK, PieceType.ROOK),
BLACK_QUEEN (PlayerType.BLACK, PieceType.QUEEN),
BLACK_KING (PlayerType.BLACK, PieceType.KING),
WHITE_PAWN (PlayerType.WHITE, PieceType.PAWN),
WHITE_KNIGHT (PlayerType.WHITE, PieceType.KNIGHT),
WHITE_BISHOP (PlayerType.WHITE, PieceType.BISHOP),
WHITE_ROOK (PlayerType.WHITE, PieceType.ROOK),
WHITE_QUEEN (PlayerType.WHITE, PieceType.QUEEN),
WHITE_KING (PlayerType.WHITE, PieceType.KING);
private final PlayerType _playerType;
private final PieceType _pieceType;
private final char[] _symbol;
private PlayerPiece(
final PlayerType playerType,
final PieceType pieceType) {
_playerType = playerType;
_pieceType = pieceType;
_symbol = new char[] {playerType.symbol(), pieceType.symbol()};
}
public final PlayerType playerType() { return _playerType; }
public final PieceType pieceType() { return _pieceType; }
public final String symbol() { return String.valueOf(_symbol); }
}
查找如...
int playerTypeOrdinal = PlayerType.WHITE.ordinal();
int pieceTypeOrdinal = PieceType.QUEEN.ordinal();
PlayerPiece playerPiece = Lookup(playerTypeOrdinal, pieceTypeOrdinal)
... 应该尽快返回 WHITE_QUEEN PlayerPiece 枚举。 我可以使用 for 循环,但是我不确定这是最快的方法。 我想使用静态 Map 但不确定如何使用两个序数作为键。
任何建议如何有效地做到这一点?
来自接受答案的解决方案
即使作为交错数组,这也有效,但是如果我不使它们平行,则存在抛出 ArrayIndexOutOfBoundsException 的可能性:
public class PlayerPieceLookup {
private static final PlayerPiece[][] PLAYER_PIECES = new PlayerPiece[][] {
{
PlayerPiece.NONE,
PlayerPiece.NONE,
PlayerPiece.NONE,
PlayerPiece.NONE,
PlayerPiece.NONE,
PlayerPiece.NONE,
PlayerPiece.NONE,
},
{
PlayerPiece.NONE,
PlayerPiece.BLACK_PAWN,
PlayerPiece.BLACK_KNIGHT,
PlayerPiece.BLACK_BISHOP,
PlayerPiece.BLACK_ROOK,
PlayerPiece.BLACK_QUEEN,
PlayerPiece.BLACK_KING
},
{
PlayerPiece.NONE,
PlayerPiece.WHITE_PAWN,
PlayerPiece.WHITE_KNIGHT,
PlayerPiece.WHITE_BISHOP,
PlayerPiece.WHITE_ROOK,
PlayerPiece.WHITE_QUEEN,
PlayerPiece.WHITE_KING
}
};
public static void main(String[] args) {
for(PlayerType player : PlayerType.values()) {
for(PieceType piece : PieceType.values()) {
System.out.println("[" + player + "][" + piece + "][" + PLAYER_PIECES[player.ordinal()][piece.ordinal()] + "]");
}
}
}
}
二维数组可以非常有效地做到这一点。 只需填充一个数组(例如在一个静态块中),这样arr[m][n]
是第 m 个玩家,第 n 个棋子。 查找将是两个数组加载(因为 Java 2d 数组是数组的数组)。
不要使用ordinal
。 这不是它的目的。 本质上,它是一个内部实现细节。
它也不是类型安全的(如果你把两个序数弄错了怎么办?)。
直接使用枚举值从EnumMap
查找。
Map<PlayerType, Map<PieceType, PlayerPiece>> map = new EnumMap<>(PlayerType.class);
for (PlayerPiece p : PlayerPiece.values()) {
map.computeIfAbsent(p.playerType(), k -> new EnumMap<>(PieceType.class))
.put(p.pieceType(), p);
}
然后使用以下方法查找一块:
map.get(playerType).get(pieceType)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.