簡體   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