呼唤一个动态的' HashMap的对象

时间:2017-12-01 21:52:21

标签: java hashmap

我刚刚遇到了我想在HashMap中调用Object函数的问题。我已经搜索过它并发现了一个帖子,但遗憾的是我不理解它。

所以这是我的代码

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? 
}

我希望我的意图是合理的。如果我的代码糟透了,请随意纠正我。我已经为它道歉了。

非常感谢。

3 个答案:

答案 0 :(得分:2)

从版本5开始,Java有一个名为 Generics 的功能。您可以在Web上找到很多关于泛型的内容,从文章,博客文章等到StackOverflow上的非常好的答案。

泛型允许Java成为强类型语言。这意味着Java中的变量不仅可以声明为某种类型(即HashMap),还可以是某种类型以及一个或多个泛型类型参数(即{ {1}},其中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更改为HashMapMap是一个类,而HashMap只是一个接口。问题是Map类实现了HashMap接口,因此,除非您的代码明确需要访问未在Map接口中声明的HashMap方法(几乎从来不是这种情况),Map变量的类型为mySeats而不是Map<Integer, Seat>,你可以。这被称为编程到接口,是一个你应该从一开始就接受的最佳实践。它将在未来为您节省很多麻烦。

答案 1 :(得分:1)

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

请使用像IntelliJ IDEA这样的IDE。它会告诉你在输入时忘记括号的错误。

答案 2 :(得分:1)

根据我在评论中的提示,我不会使用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()));
    }
}