我们正在做一个基于文本的冒险,您从JSON文件中读取布局。我正在读取JSON文件以创建一个包含房间对象的Layout类。每个房间都有一个方向图,该方向图将方向名称(即南,东,西等)映射到方向对象。在布局类内部,还有另一个映射,将房间名称映射到房间对象。当我运行代码时,调试器告诉我roomMap和directionMap均为null。因此,当我尝试调用JUnit测试以确保在访问地图时返回正确的值时,会收到NullPointerException。
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.HashMap;
public class Room {
// instance variables
protected String name;
protected String description;
protected Item[] items;
protected Direction[] directions;
protected ArrayList<Direction> testList = new ArrayList<>();
protected HashMap<String, Direction> directionMap = new HashMap<>();
public Room(String name, String description, Direction[] directions, Item[] items) {
this.name = name;
this.description = description;
this.items = items;
this.directions = directions;
for (Direction d : directions) {
directionMap.put(d.directionName, d);
}
}
}
这是我的指导班:
package com.example;
import com.sun.org.apache.xpath.internal.operations.Bool;
public class Direction {
// instance variables
protected String room;
protected String directionName;
protected boolean enabled;
protected String[] validKeyNames;
public Direction(String room, String directionName, String enabled, String[] validKeyNames) {
this.room = room;
this.directionName = directionName;
this.enabled = Boolean.parseBoolean(enabled);
this.validKeyNames = validKeyNames;
}
public static boolean compareDirections (Direction d1, Direction d2){
boolean roomMatch = d1.room.equals(d2.room);
boolean nameMatch = d1.directionName.equals(d2.directionName);
boolean enabledMatch = d1.enabled == d2.enabled;
boolean validKeyNamesMatch = true;
if(d1.validKeyNames.length == d2.validKeyNames.length){
for(int i = 0; i < d1.validKeyNames.length; i++){
if(!d1.validKeyNames[i].equals(d2.validKeyNames[i])){
validKeyNamesMatch = false;
}
}
}
return roomMatch && nameMatch && enabledMatch && validKeyNamesMatch;
}
}
这是我的Player课:
public class Player {
protected Item[] items;
protected Room currentRoom;
public Player(Item[] items, Room startingRoom){
this.items = items;
this.currentRoom = startingRoom;
}
}
这是我的Items类:
public class Item {
protected String name;
public Item(String name){
this.name = name;
}
public static boolean compareItems (Item i1, Item i2){
return i1.name.equals(i2.name);
}
}
这是我的布局类,其中roomMap在其中
public class Layout {
// instance variables
protected String startingRoom;
protected String endingRoom;
protected Room[] rooms;
protected Player player;
protected HashMap<String, Room> roomMap = new HashMap<>();
public Layout(String startingRoom, String endingRoom, Room[] rooms, Player player) {
this.startingRoom = startingRoom;
this.endingRoom = endingRoom;
this.rooms = rooms;
this.player = player;
for (Room room : rooms) {
roomMap.put(room.name, room);
}
}
这是JSON阅读器类:
public class JsonReader {
public static String getJsonFromUrl (String link) throws IOException {
try{
URL url = new URL(link);
} catch(MalformedURLException e){
System.out.println("That is not a valid link");
System.exit(0);
}
URL url = new URL(link);
// Connect to the URL using java's native library
URLConnection request = url.openConnection();
request.connect();
// Convert to a JSON object to print data
JsonParser jp = new JsonParser(); //from gson
JsonElement root = jp.parse(new InputStreamReader((InputStream) request.getContent())); //Convert the input stream to a json element
JsonObject rootobj = root.getAsJsonObject(); //May be an array, may be an object.
return rootobj.toString();
}
}
我已经测试了Gson解析器,并且知道JSON文件中的所有值都已正确序列化的事实,这就是为什么我对键值对没有放入哈希图中感到困惑的原因。
这是我的JUnit测试
import com.google.gson.Gson;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import java.io.IOException;
import static org.junit.Assert.*;
public class AdventureTest {
Adventure adventure;
@Before
public void setup() {
adventure = new Adventure("https://drive.google.com/uc?export=download&id=1qmmrC3jZ3zrmdvrL8ukM5r4pB4BYhfyd");
}
@Test
public void getJsonFromUrlTest() throws IOException {
assertEquals(
"{\"startingRoom\":\"SDRPCommons\",\"endingRoom\":\"HopkinsRoom345\",\"rooms\":[{\"name\":\"SDRPCommons\",\"description\":\"You are in the Ikenberry Dining Hall. There is good food, good people, and good study areas\",\"directions\":[{\"directionName\":\"North\",\"room\":\"DiningHall\",\"enabled\":\"false\",\"validKeyNames\":[\"I-card\"]},{\"directionName\":\"Northwest\",\"room\":\"UpstairsArea\",\"enabled\":\"true\",\"validKeyNames\":[]},{\"directionName\":\"West\",\"room\":\"OutsideAreaOfSixPack\",\"enabled\":\"false\",\"validKeyNames\":[\"backpack\",\"depression\"]}],\"items\":[{\"name\":\"I-card\"},{\"name\":\"Chair\"},{\"name\":\"Fork\"}]},{\"name\":\"DiningHall\",\"description\":\"The best eats on campus, other than PAR/FAR, Chomps, and basically anything on Green Street.\",\"directions\":[{\"directionName\":\"South\",\"room\":\"SDRPCommons\",\"enabled\":\"true\",\"validKeyNames\":[\"depression\"]}],\"items\":[{\"name\":\"sweatshirt\"},{\"name\":\"key\"}]},{\"name\":\"UpstairsArea\",\"description\":\"You are upstairs. Near you is Caffeinator but it's closed. So there is nothing to do but to go back to your room and grind...\",\"directions\":[{\"directionName\":\"Southeast\",\"room\":\"SDRPCommons\",\"enabled\":\"true\",\"validKeyNames\":[]}],\"items\":[{\"name\":\"depression\"},{\"name\":\"backpack\"}]},{\"name\":\"OutsideAreaOfSixPack\",\"description\":\"It's a beautiful day and everyone is out and about. Kinda makes you want to sit in your room in the dark, right?\",\"directions\":[{\"directionName\":\"North\",\"room\":\"HopkinsRoom345\",\"enabled\":\"false\",\"validKeyNames\":[\"depression\",\"backpack\"]}],\"items\":[{\"name\":\"depression\"},{\"name\":\"backpack\"}]},{\"name\":\"HopkinsRoom345\",\"description\":\"This is your room. Go inside and grind your cs 126 hw, idiot.\",\"directions\":[{\"directionName\":\"South\",\"room\":\"OutsideAreaOfSixPack\",\"enabled\":\"false\",\"validKeyNames\":[\"key\",\"depression\"]}],\"items\":[{\"name\":\"bed\"}]}]}",
JsonReader.getJsonFromUrl("https://drive.google.com/uc?export=download&id=1qmmrC3jZ3zrmdvrL8ukM5r4pB4BYhfyd")
);
}
@Test
public void loadJsonIntoLayout() throws IOException {
String json = JsonReader.getJsonFromUrl("https://drive.google.com/uc?export=download&id=1qmmrC3jZ3zrmdvrL8ukM5r4pB4BYhfyd");
Gson gson = new Gson();
Layout layout = gson.fromJson(json, Layout.class);
if (layout != null) {
assertEquals("SDRPCommons", layout.startingRoom);
// System.out.println(layout.roomMap.get(layout.startingRoom));
Room r = adventure.roomMap.get("DiningHall");
Direction d = adventure.directionMap.get("south");
String s = d.directionName;
assertEquals("south", layout.roomMap.get("DiningHall").directionMap.get("south"));
}
}
}
这是冒险课:
import com.google.gson.Gson;
import java.io.*;
import java.lang.reflect.Array;
import java.net.*;
import java.util.*;
import static sun.plugin.javascript.navig.JSType.Element;
public class Adventure {
protected Layout layout;
protected HashMap<String, Room> roomMap = new HashMap<>();
protected HashMap<String, Direction> directionMap = new HashMap<>();
// private Player player;
private static String jsonUrl;
// link for easy access: https://drive.google.com/uc?export=download&id=1qmmrC3jZ3zrmdvrL8ukM5r4pB4BYhfyd
protected Room currentRoom;
protected final List<String> ACTION_VERBS = Arrays.asList("go");
protected final List<String> EXIT_VERBS = Arrays.asList("exit", "quit");
protected final List<String> ITEM_VERBS = Arrays.asList("pickup", "use");
public Adventure(String url) {
this.jsonUrl = url;
this.layout = getLayoutFromJson(jsonUrl);
String startingRoom = layout.getStartingRoom();
for (Room r : layout.rooms) {
for (Direction d : r.directions) {
r.directionMap.put(d.directionName, d);
}
layout.roomMap.put(r.name, r);
}
this.currentRoom = roomMap.get(startingRoom);
}
public Layout getLayoutFromJson(String url) {
try {
String json = JsonReader.getJsonFromUrl(url);
Gson gson = new Gson();
Layout layout = gson.fromJson(json, Layout.class);
return layout;
} catch (Exception e) {
return null;
}
}
}
答案 0 :(得分:1)
Gson不会自动调用非默认构造函数。它要么调用no-args构造函数,要么“自动”创建一个实例,然后通过反射填充其字段。阅读Is default no-args constructor mandatory for Gson?
这意味着您的roomMap
/ directionMap
填充代码将不会被调用,因为该代码位于非默认构造函数中。