繁体   English   中英

Java中基于查找两个整数来查找特定枚举的最快方法

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM