我刚刚遇到了我想在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?
}
我希望我的意图是合理的。如果我的代码糟透了,请随意纠正我。我已经为它道歉了。
非常感谢。
答案 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
更改为HashMap
。 Map
是一个类,而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()));
}
}