所以我有以下问题:
情况1
特定类型的宇宙飞船只能在数据存储中存储一次。因此,如果用户尝试存储以下内容,则名称1:太空船类型1和名称2:太空船类型1只有1个宇宙飞船类型1的实例将存储在数据结构中。
情况2
如果用户输入名称1:太空船类型1,然后输入名称1:太空飞船类型2,则数据结构应仅存储名称1:太空飞船类型2.这意味着太空船类型1已被太空飞船类型2替换为他们有相同的名字。
我对此问题的初步处理方法是使用哈希映射,我会对太空船ID进行哈希处理,这样如果两个太空船ID相同,我将只在哈希映射中存储一次太空船ID,并且值我将有一个映射到相同的太空船ID的名称数组。这解决了情况1.
情况2更成问题。哈希映射可能非常大,我认为迭代每个桶中的每个数组都是低效的,以便识别是否已经使用了一个名称,以便从哈希映射中删除该名称和潜在的太空船ID并添加一个条目使用新的太空船ID及其相应的名称。
在这种情况下,哈希映射最好使用,还是可以使用另一种数据结构来解决这两种情况。也许我必须自己创造一个。任何正确方向的指针都会有所帮助。
答案 0 :(得分:0)
单独的地图将是理想的,但如果您决定绕过任何第三方图书馆(我不同意的决定,除非目的是学习如何创建自己的Map
),那么最容易想到的就是你有两个Maps
Map<String, String> typeToName; //if you could have multiple of the Value, it could be Set<String>
Map<String, String> nameToType;
//put "Type1", "DoubleDouble's Destroyer" in typeToName
//put "DoubleDouble's Destroyer", "Type1" in nameToType
如果您要添加"Type1", "DistractionBoat"
,则首先要查看"Type1"
中是否有typeToName
,并从nameToType
中删除相应的名称。
然后你反过来检查"DistractionBoat"
中是否有nameToType
,并从type
typeToName
然后添加新的太空船,它将替换同一type
或 name
的任何太空船。
可能有许多改进可以在此基础上构建(最明显的是使其更通用和自己的类)。事实上,你为了速度牺牲了记忆。
答案 1 :(得分:0)
您可以使用两个地图实现自己的类,如下所示:
public final class Spaceship {
private final int id;
private final String name;
public Spaceship(int id, String name) {
this.id = id;
this.name = name;
}
public int getId() {
return this.id;
}
public String getName() {
return this.name;
}
@Override
public String toString() {
return this.id + ":" + this.name;
}
}
public final class Spacedock {
private Map<Integer, Spaceship> byId = new HashMap<>();
private Map<String, Spaceship> byName = new TreeMap<>(); // so getSpaceships() lists ordered by name
public boolean containsSpaceship(Spaceship spaceship) {
Spaceship shipInDock = this.byId.get(spaceship.getId());
return (shipInDock != null && shipInDock.getName().equals(spaceship.getName()));
}
public void addSpaceship(Spaceship spaceship) {
if (! containsSpaceship(spaceship)) {
Spaceship prevShip = this.byId.put(spaceship.getId(), spaceship);
if (prevShip != null)
this.byName.remove(prevShip.getName());
prevShip = this.byName.put(spaceship.getName(), spaceship);
if (prevShip != null)
this.byId.remove(prevShip.getId());
}
}
public void removeSpaceship(Spaceship spaceship) {
if (containsSpaceship(spaceship)) {
this.byId.remove(spaceship.getId());
this.byName.remove(spaceship.getName());
}
}
public Collection<Spaceship> getSpaceships() {
return this.byName.values();
}
public Spaceship getById(int id) {
return this.byId.get(id);
}
public Spaceship getName(String name) {
return this.byName.get(name);
}
@Override
public String toString() {
return this.byName.values().toString();
}
}
测试
Spacedock spacedock = new Spacedock();
spacedock.addSpaceship(new Spaceship(1, "Name1"));
System.out.println(spacedock);
spacedock.addSpaceship(new Spaceship(2, "Name2"));
System.out.println(spacedock);
spacedock.addSpaceship(new Spaceship(1, "Name2"));
System.out.println(spacedock);
spacedock.addSpaceship(new Spaceship(2, "Name2"));
System.out.println(spacedock);
spacedock.addSpaceship(new Spaceship(2, "Name1"));
System.out.println(spacedock);
输出
[1:Name1]
[1:Name1, 2:Name2]
[1:Name2]
[2:Name2]
[2:Name1]
如您所见,存储了不同的太空飞船,通过添加一个已存在的ID或名称的新船将删除现有的船只。
如果您使用的是Java 8并且不喜欢空值,请使用新的Optional
:
public Optional<Spaceship> getById(int id) {
return Optional.ofNullable(this.byId.get(id));
}
public Optional<Spaceship> getName(String name) {
return Optional.ofNullable(this.byName.get(name));
}