簡體   English   中英

調用HashMap的“動態”對象

[英]Calling a 'dynamic' Object of a HashMap

我剛遇到要在HashMap中調用對象函數的問題。 我已經對其進行了搜索,找到了一個線程,但可惜我不理解。

所以這是我的代碼

public class Seat {

  //some attributes

  public int getNumber() {
     return number;
  }
  public boolean isReserved() {
     return status;
  }
}

public class Hall {

  private HashMap mySeats;

  public HashMap getMeinePlaetze() {
      return meinePlaetze;
  }
  public void createSeats() {
      for (int i = 1; i <= this.getnumberOfSeats(); i++) {
        this.getMySeats().put(i, new Seat(i, 1));
      }
   }
}
public class Main {
  Hall h1 = new Hall(...);

  h1.createSeats();

  h1.getMySeats().get(2).isReserved();  //How do I have to write this to work out? 
}

我希望我的意圖是合理的。 如果我的代碼很爛,請隨時糾正我。 我已經為此道歉。

非常感謝你。

從版本5開始,Java具有稱為Generics的功能。 您可以在網上找到很多有關泛型的信息,從文章,博客文章等到StackOverflow上的非常好的答案。

泛型允許Java成為強類型語言。 這意味着Java中的變量不僅可以聲明為某種類型(即HashMap ),而且還可以聲明為某種類型以及一個或多個通用類型參數 (即HashMap<K, V> ,其中K表示類型)圖的鍵的參數, V代表圖的值的類型參數)。

在您的示例中,您使用的是原始HashMap (原始類型是允許指定泛型類型參數的類型,但是開發人員尚未指定它們)。 正如您現在所遇到的那樣,原始類型被認為是不好的做法,並且很容易出錯。

HashMap允許兩個通用類型參數(一個用於鍵,另一個用於值)。 在您的情況下,您將Integer用於鍵,將Seat用於值。 簡而言之,您是將整數映射到席位,或者也可以說您的映射是整數到席位的映射。

因此,在Hall類中,應使用其通用類型參數定義地圖:

private Map<Integer, Seat> mySeats = new HashMap<>();

然后,此代碼:

h1.getMySeats().get(2)

將返回一個Seat類型的實例,因為您的地圖已經知道其所有值都為Seat類型。

所以你的代碼:

h1.getMySeats().get(2).isReserved();

可以正常編譯,並且不會出現任何錯誤。

請注意,除了聲明地圖的通用類型外,我還更改了兩點。

首先,我使用其構造函數創建了一個HashMap的實際實例:

mySeats = new HashMap<>()

如果不使用new創建您的類型的實例,則以后將不會再有任何HashMap實例放置您的位置,並且您將獲得NullpointerException (嘗試!)。

其次,我將變量的類型從HashMap更改為Map HashMap是一個類,而Map只是一個接口。 事實是HashMap類實現了Map接口,因此,除非您的代碼明確需要訪問未在Map接口中聲明的HashMap方法(這幾乎是不可能的),否則使用mySeats變量就可以了的類型為Map<Integer, Seat>而不是HashMap<Integer, Seat> 這就是所謂的接口編程,它是您從一開始就應該接受的最佳實踐。 它將在將來為您節省很多麻煩。

h1.getMySeats().get(2).isReserved();

請使用像IntelliJ IDEA這樣的IDE。 它會告訴您一些錯誤,例如在鍵入時忘記括號。

遵循我在注釋中的提示,我不會使用Map將有意義的行或數字鏈接到map-key或array-index。

因此,實際上我會這樣做(因為您問過,我對小費的意思):

座位:

public class Seat {

    private final int row;
    private final int number;
    private boolean reserved = false;

    public Seat(int row, int number) {
        this.row = row;
        this.number = number;
    }

    public boolean reserve() {
        if (!reserved) {
            reserved = true;
            return reserved;
        }
        return !reserved;
    }

    public int getRow() {
        return row;
    }

    public int getNumber() {
        return number;
    }

    public boolean isReserved() {
        return reserved;
    }

    public boolean is(int row, int number) {
        return this.row == row && this.number == number;
    }

    @Override
    public int hashCode() {
        int hash = 7;
        hash = 23 * hash + this.row;
        hash = 23 * hash + this.number;
        return hash;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        final Seat other = (Seat) obj;
        if (this.row != other.row) {
            return false;
        }
        return number == other.number;
    }
}

大廳:

public class Hall {

    public final Set<Seat> seats = new HashSet<>();

    public Set<Seat> getSeats() {
        return Collections.unmodifiableSet(seats);
    }

    public void createSeats(int lastRow, int seatsPerRow) { // This is an example; in case you have different count of seats per row, you better make an boolean addSeat(int row, int number) function; boolean to check if it has been added or if the seat already exists
        for (int row = 1; row <= lastRow; row++) {
            for (int number = 1; number <= seatsPerRow; number++) {
                seats.add(new Seat(row, number));
            }
        }
    }

    public Seat get(int row, int number) {
        for (Seat seat : seats) { // or you use seats.iterator; I personally hate Iterators; it is my subjective point of view.
            if (seat.is(row, number)) {
                return seat;
            }
        }
        return null;
    }

    public boolean reserve(int row, int number) {
        Seat seat = get(row, number);
        if (seat != null) {
            return seat.reserve();
        }
        return false;
    }
}

而我的試駕:

public class TestDrive {

    public static void main(String[] args) {
        Hall hall = new Hall();
        int lastRow = 15;
        int seatsPerRow = 10;
        hall.createSeats(lastRow, seatsPerRow);

        boolean reserved = hall.reserve(5, 9);
        System.out.println("Seat(Row=5, Number=9) is reserved: " + (reserved == hall.get(5, 9).isReserved()));

        boolean reservedAgain = hall.reserve(5, 9);
        System.out.println("Seat(Row=5, Number=9) cannot be reserved again: " + (reservedAgain != hall.get(5, 9).isReserved()));
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM