Java:将嵌套的JSON文件转换成单个的下一个ArrayList

时间:2019-11-22 02:46:03

标签: java json parsing

我正在寻求将嵌套的JSON文件转换为一个单个的下一个Java ArrayList。

这是我的JSON文件的摘要:

[
    {
        "dex": "001",
        "name": "Bulbasaur",
        "types": [
            "Grass",
            "Poison"
        ],
        "attack": 128,
        "defense": 118,
        "HP": 111,
        "catchRate": 0.2,
        "fleeRate": 0.1,
        "candy": 25,
        "fastMoves": [
            "Vine Whip",
            "Tackle"
        ],
        "chargeMoves": [
            "Seed Bomb",
            "Sludge Bomb",
            "Power Whip"
        ]
    },
    {
        "dex": "002",
        "name": "Ivysaur",
        "types": [
            "Grass",
            "Poison"
        ],
        "attack": 155,
        "defense": 151,
        "HP": 143,
        "catchRate": 0.1,
        "fleeRate": 0.07,
        "candy": 100,
        "fastMoves": [
            "Vine Whip",
            "Razor Leaf"
        ],
        "chargeMoves": [
            "Sludge Bomb",
            "Solar Beam",
            "Power Whip"
        ]
    }
]

这是我到目前为止拥有的Java:

JSONParser parser = new JSONParser();
        JSONObject jsonObject = null;

        try {
            JSONArray jo = (JSONArray) parser.parse(new FileReader(filePath));

            ArrayList<JSONObject> pokemons = new ArrayList<JSONObject>();

            for (int i = 0; i < jo.size(); i++) {
                JSONObject pokemon = (JSONObject) jo.get(i);
                pokemons.add(pokemon);
            }


            return pokemons;

        } catch (ParseException | IOException e) {
            System.out.println("File not found.");
            return null;
        }
    }

目前,我的Java允许人们从任何词典项目中访问任何值。但是,我无法访问任何词典中的任何列表中的任何项目(“类型”,“ fastMoves”,“ chargeMoves”)。如何解析此信息,以便可以访问这些列表的列表项?

例如,如何编辑主ArrayList,以便在执行以下操作调用时:pokemons.get(1).get(“types”).get(1),它将返回“Poison”

3 个答案:

答案 0 :(得分:0)

当您解析JSON时,JSON将转换为Map中的JAVA对象。

在您的情况下,ArrayList中的每个对象都是一个Map。您可以通过将key传递给get方法来访问必填字段。

JSONArray jo = (JSONArray) parser.parse(input);

ArrayList<JSONObject> pokemons = new ArrayList<JSONObject>();

for (int i = 0; i < jo.size(); i++) {
    JSONObject pokemon = (JSONObject) jo.get(i);
    pokemons.add(pokemon);
}

// now from here you can access the values by passing keys
// for dex: 001
JSONObject pok = pokemons.get(0); // contains whole dex: 001 object
// access values by keys
System.err.println(pok.get("dex")); // outputs :  001
// to access nested array
JSONArray jsonArray = (JSONArray) pok.get("types");
System.out.println(jsonArray); // will print ["Grass","Poison"]

for(Object str: jsonArray) {
    System.out.println(str); // will print Grass
}

答案 1 :(得分:0)

更新:结尾处包含一个简单的json示例。


我将直接从GAME_MASTER中读取内容,并找到templateId符合以下表达式的项目:^V\d{4}_POKEMON_\w+$

然后将数据映射到POJO,例如Pokemon.java

以下是使用Google GSON的示例:

implementation 'com.google.code.gson:gson:2.8.6'

PokemonGoReader

package pokemon.parse;

import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Pattern;

import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;

public class PokemonGoReader {
    private static String GAME_MASTER_URL = "https://raw.githubusercontent.com/PokeMiners/game_masters/master/latest/latest.json";
    public static Pattern POKEMON_TEMPLATE = Pattern.compile("^V\\d{4}_POKEMON_\\w+$");

    public static void main(String[] args) {
        try {
            List<Pokemon> pokemonList = getPokemon();
            pokemonList.stream().forEach(System.out::println);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static List<Pokemon> getPokemon() throws MalformedURLException, IOException {
        BufferedInputStream in = new BufferedInputStream(new URL(GAME_MASTER_URL).openStream());
        InputStreamReader reader = new InputStreamReader(in, StandardCharsets.UTF_8);
        JsonArray templateArray = JsonParser.parseReader(reader).getAsJsonArray();
        List<Pokemon> pokemonList = new ArrayList<Pokemon>();

        templateArray.forEach(template -> {
            JsonObject data = template.getAsJsonObject();
            String templateId = data.get("templateId").getAsString();

            if (POKEMON_TEMPLATE.matcher(templateId).matches()) {
                JsonObject pokemonSettings = data.get("pokemonSettings").getAsJsonObject();
                String pokemonId = pokemonSettings.get("pokemonId").getAsString();

                List<Type> types = new ArrayList<>();
                types.add(Type.valueOf(pokemonSettings.get("type").getAsString().replace("POKEMON_TYPE_", "")));
                if (pokemonSettings.has("type2")) {
                    types.add(Type.valueOf(pokemonSettings.get("type2").getAsString().replace("POKEMON_TYPE_", "")));
                }

                List<String> fastAttacks = new ArrayList<>();
                if (pokemonSettings.has("quickMoves")) {
                    JsonArray quickMoves = pokemonSettings.get("quickMoves").getAsJsonArray();
                    quickMoves.forEach(quickMove -> fastAttacks.add(quickMove.getAsString()));
                }

                List<String> chargedAttacks = new ArrayList<>();
                if (pokemonSettings.has("cinematicMoves")) {
                    JsonArray cinematicMoves = pokemonSettings.get("cinematicMoves").getAsJsonArray();
                    cinematicMoves.forEach(cinematicMove -> chargedAttacks.add(cinematicMove.getAsString()));
                }

                Pokemon pokemon = new Pokemon();
                pokemon.setTemplateId(templateId);
                pokemon.setName(pokemonId);
                pokemon.setTypes(types);
                pokemon.setFastAttacks(fastAttacks);
                pokemon.setChargedAttacks(chargedAttacks);
                pokemonList.add(pokemon);
            }
        });

        return pokemonList;
    }
}

Pokemon

package pokemon.parse;

import java.util.List;

public class Pokemon {
    private String templateId;
    private String name;
    private List<Type> types;
    private List<String> fastAttacks;
    private List<String> chargedAttacks;

    public String getTemplateId() {
        return templateId;
    }

    public void setTemplateId(String templateId) {
        this.templateId = templateId;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public List<Type> getTypes() {
        return types;
    }

    public void setTypes(List<Type> types) {
        this.types = types;
    }

    public List<String> getFastAttacks() {
        return fastAttacks;
    }

    public void setFastAttacks(List<String> fastAttacks) {
        this.fastAttacks = fastAttacks;
    }

    public List<String> getChargedAttacks() {
        return chargedAttacks;
    }

    public void setChargedAttacks(List<String> chargedAttacks) {
        this.chargedAttacks = chargedAttacks;
    }

    @Override
    public String toString() {
        return String.format("Pokemon [templateId=%s, name=%s, types=%s, fastAttacks=%s, chargedAttacks=%s]",
                templateId, name, types, fastAttacks, chargedAttacks);
    }
}

类型

package pokemon.parse;

public enum Type {
    NORMAL,
    FIRE,
    FIGHTING,
    WATER,
    FLYING,
    GRASS,
    POISON,
    ELECTRIC,
    GROUND,
    PSYCHIC,
    ROCK,
    ICE,
    BUG,
    DRAGON,
    GHOST,
    DARK,
    STEEL,
    FAIRY;
}

输出

Pokemon [templateId=V0001_POKEMON_BULBASAUR, name=BULBASAUR, types=[GRASS, POISON], fastAttacks=[VINE_WHIP_FAST, TACKLE_FAST], chargedAttacks=[SLUDGE_BOMB, SEED_BOMB, POWER_WHIP]]
Pokemon [templateId=V0002_POKEMON_IVYSAUR, name=IVYSAUR, types=[GRASS, POISON], fastAttacks=[RAZOR_LEAF_FAST, VINE_WHIP_FAST], chargedAttacks=[SLUDGE_BOMB, SOLAR_BEAM, POWER_WHIP]]
Pokemon [templateId=V0003_POKEMON_VENUSAUR, name=VENUSAUR, types=[GRASS, POISON], fastAttacks=[RAZOR_LEAF_FAST, VINE_WHIP_FAST], chargedAttacks=[SLUDGE_BOMB, PETAL_BLIZZARD, SOLAR_BEAM]]
Pokemon [templateId=V0004_POKEMON_CHARMANDER, name=CHARMANDER, types=[FIRE], fastAttacks=[EMBER_FAST, SCRATCH_FAST], chargedAttacks=[FLAME_CHARGE, FLAME_BURST, FLAMETHROWER]]
Pokemon [templateId=V0005_POKEMON_CHARMELEON, name=CHARMELEON, types=[FIRE], fastAttacks=[EMBER_FAST, FIRE_FANG_FAST], chargedAttacks=[FIRE_PUNCH, FLAME_BURST, FLAMETHROWER]]
Pokemon [templateId=V0006_POKEMON_CHARIZARD, name=CHARIZARD, types=[FIRE, FLYING], fastAttacks=[FIRE_SPIN_FAST, AIR_SLASH_FAST], chargedAttacks=[FIRE_BLAST, DRAGON_CLAW, OVERHEAT]]
Pokemon [templateId=V0007_POKEMON_SQUIRTLE, name=SQUIRTLE, types=[WATER], fastAttacks=[BUBBLE_FAST, TACKLE_FAST], chargedAttacks=[AQUA_JET, AQUA_TAIL, WATER_PULSE]]
Pokemon [templateId=V0008_POKEMON_WARTORTLE, name=WARTORTLE, types=[WATER], fastAttacks=[WATER_GUN_FAST, BITE_FAST], chargedAttacks=[AQUA_JET, ICE_BEAM, HYDRO_PUMP]]
Pokemon [templateId=V0009_POKEMON_BLASTOISE, name=BLASTOISE, types=[WATER], fastAttacks=[WATER_GUN_FAST, BITE_FAST], chargedAttacks=[FLASH_CANNON, ICE_BEAM, HYDRO_PUMP, SKULL_BASH]]
Pokemon [templateId=V0010_POKEMON_CATERPIE, name=CATERPIE, types=[BUG], fastAttacks=[BUG_BITE_FAST, TACKLE_FAST], chargedAttacks=[STRUGGLE]]
Pokemon [templateId=V0011_POKEMON_METAPOD, name=METAPOD, types=[BUG], fastAttacks=[BUG_BITE_FAST, TACKLE_FAST], chargedAttacks=[STRUGGLE]]
Pokemon [templateId=V0012_POKEMON_BUTTERFREE, name=BUTTERFREE, types=[BUG, FLYING], fastAttacks=[STRUGGLE_BUG_FAST, CONFUSION_FAST], chargedAttacks=[BUG_BUZZ, PSYCHIC, SIGNAL_BEAM]]
Pokemon [templateId=V0013_POKEMON_WEEDLE, name=WEEDLE, types=[BUG, POISON], fastAttacks=[BUG_BITE_FAST, POISON_STING_FAST], chargedAttacks=[STRUGGLE]]
Pokemon [templateId=V0014_POKEMON_KAKUNA, name=KAKUNA, types=[BUG, POISON], fastAttacks=[BUG_BITE_FAST, POISON_STING_FAST], chargedAttacks=[STRUGGLE]]
Pokemon [templateId=V0015_POKEMON_BEEDRILL, name=BEEDRILL, types=[BUG, POISON], fastAttacks=[INFESTATION_FAST, POISON_JAB_FAST], chargedAttacks=[SLUDGE_BOMB, AERIAL_ACE, X_SCISSOR]]
Pokemon [templateId=V0016_POKEMON_PIDGEY, name=PIDGEY, types=[NORMAL, FLYING], fastAttacks=[QUICK_ATTACK_FAST, TACKLE_FAST], chargedAttacks=[TWISTER, AERIAL_ACE, AIR_CUTTER]]
Pokemon [templateId=V0017_POKEMON_PIDGEOTTO, name=PIDGEOTTO, types=[NORMAL, FLYING], fastAttacks=[WING_ATTACK_FAST, STEEL_WING_FAST], chargedAttacks=[TWISTER, AERIAL_ACE, AIR_CUTTER]]
Pokemon [templateId=V0018_POKEMON_PIDGEOT, name=PIDGEOT, types=[NORMAL, FLYING], fastAttacks=[AIR_SLASH_FAST, STEEL_WING_FAST], chargedAttacks=[HURRICANE, AERIAL_ACE, BRAVE_BIRD]]
Pokemon [templateId=V0019_POKEMON_RATTATA, name=RATTATA, types=[NORMAL], fastAttacks=[TACKLE_FAST, QUICK_ATTACK_FAST], chargedAttacks=[DIG, HYPER_FANG, BODY_SLAM]]
Pokemon [templateId=V0019_POKEMON_RATTATA_ALOLA, name=RATTATA, types=[DARK, NORMAL], fastAttacks=[TACKLE_FAST, QUICK_ATTACK_FAST], chargedAttacks=[CRUNCH, HYPER_FANG, SHADOW_BALL]]
Pokemon [templateId=V0020_POKEMON_RATICATE, name=RATICATE, types=[NORMAL], fastAttacks=[BITE_FAST, QUICK_ATTACK_FAST], chargedAttacks=[DIG, HYPER_FANG, HYPER_BEAM]]
Pokemon [templateId=V0020_POKEMON_RATICATE_ALOLA, name=RATICATE, types=[DARK, NORMAL], fastAttacks=[BITE_FAST, QUICK_ATTACK_FAST], chargedAttacks=[CRUNCH, HYPER_FANG, HYPER_BEAM]]
Pokemon [templateId=V0021_POKEMON_SPEAROW, name=SPEAROW, types=[NORMAL, FLYING], fastAttacks=[PECK_FAST, QUICK_ATTACK_FAST], chargedAttacks=[AERIAL_ACE, DRILL_PECK, SKY_ATTACK]]
Pokemon [templateId=V0022_POKEMON_FEAROW, name=FEAROW, types=[NORMAL, FLYING], fastAttacks=[PECK_FAST, STEEL_WING_FAST], chargedAttacks=[AERIAL_ACE, DRILL_RUN, SKY_ATTACK]]
Pokemon [templateId=V0023_POKEMON_EKANS, name=EKANS, types=[POISON], fastAttacks=[POISON_STING_FAST, ACID_FAST], chargedAttacks=[WRAP, POISON_FANG, SLUDGE_BOMB]]
Pokemon [templateId=V0024_POKEMON_ARBOK, name=ARBOK, types=[POISON], fastAttacks=[BITE_FAST, ACID_FAST, DRAGON_TAIL_FAST], chargedAttacks=[DARK_PULSE, SLUDGE_WAVE, GUNK_SHOT, ACID_SPRAY]]
Pokemon [templateId=V0025_POKEMON_PIKACHU, name=PIKACHU, types=[ELECTRIC], fastAttacks=[THUNDER_SHOCK_FAST, QUICK_ATTACK_FAST], chargedAttacks=[DISCHARGE, THUNDERBOLT, WILD_CHARGE]]
Pokemon [templateId=V0026_POKEMON_RAICHU, name=RAICHU, types=[ELECTRIC], fastAttacks=[VOLT_SWITCH_FAST, SPARK_FAST, CHARM_FAST], chargedAttacks=[BRICK_BREAK, THUNDER_PUNCH, WILD_CHARGE, SKULL_BASH]]
Pokemon [templateId=V0026_POKEMON_RAICHU_ALOLA, name=RAICHU, types=[ELECTRIC, PSYCHIC], fastAttacks=[VOLT_SWITCH_FAST, SPARK_FAST, THUNDER_SHOCK_FAST], chargedAttacks=[PSYCHIC, THUNDER_PUNCH, WILD_CHARGE, GRASS_KNOT]]
...

原始口袋妖怪模板的示例

{
  templateId: "V0001_POKEMON_BULBASAUR",
  pokemonSettings: {
    pokemonId: "BULBASAUR",
    modelScale: 1.09,
    type: "POKEMON_TYPE_GRASS",
    type2: "POKEMON_TYPE_POISON",
    camera: {
      diskRadiusM: 0.57230002,
      cylinderRadiusM: 0.5,
      cylinderHeightM: 0.76300001,
      shoulderModeScale: 0.5
    },
    encounter: {
      baseCaptureRate: 0.2,
      baseFleeRate: 0.1,
      collisionRadiusM: 0.38150001,
      collisionHeightM: 0.65399998,
      collisionHeadRadiusM: 0.27250001,
      movementType: "MOVEMENT_JUMP",
      movementTimerS: 10,
      jumpTimeS: 1.15,
      attackTimerS: 29,
      attackProbability: 0.1,
      dodgeProbability: 0.15000001,
      dodgeDurationS: 1,
      dodgeDistance: 1,
      cameraDistance: 3.75,
      minPokemonActionFrequencyS: 0.2,
      maxPokemonActionFrequencyS: 1.6
    },
    stats: {
      baseStamina: 128,
      baseAttack: 118,
      baseDefense: 111
    },
    quickMoves: [
      "VINE_WHIP_FAST",
      "TACKLE_FAST"
    ],
    cinematicMoves: [
      "SLUDGE_BOMB",
      "SEED_BOMB",
      "POWER_WHIP"
    ],
    animationTime: [
      1.6667,
      0.66670001,
      1.6667,
      1.8333,
      0,
      2.1666999,
      1.4,
      1.4666671
    ],
    evolutionIds: [
      "IVYSAUR"
    ],
    evolutionPips: 1,
    pokedexHeightM: 0.69999999,
    pokedexWeightKg: 6.9000001,
    heightStdDev: 0.087499999,
    weightStdDev: 0.86250001,
    familyId: "FAMILY_BULBASAUR",
    candyToEvolve: 25,
    kmBuddyDistance: 3,
    modelHeight: 0.69999999,
    evolutionBranch: [{
      evolution: "IVYSAUR",
      candyCost: 25,
      form: "IVYSAUR_NORMAL"
    }],
    modelScaleV2: 0.88999999,
    buddyOffsetMale: [
      0,
      0,
      0
    ],
    buddyOffsetFemale: [
      0,
      0,
      0
    ],
    buddyScale: 19,
    thirdMove: {
      stardustToUnlock: 10000,
      candyToUnlock: 25
    },
    isTransferable: true,
    isDeployable: true
  }
}

简单JSON

如果您真的想使用simple-json,建议您阅读本教程。

  

https://www.mkyong.com/java/json-simple-how-to-parse-json/

在以下示例中,我在加载的data.json文件中使用了您的原始JSON。

implementation 'com.github.cliftonlabs:json-simple:3.1.0'
implementation 'net.sf.dozer:dozer:5.5.1'

简单解析

package pokemon.parse;

import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;

import org.dozer.DozerBeanMapper;
import org.dozer.Mapper;

import com.github.cliftonlabs.json_simple.JsonArray;
import com.github.cliftonlabs.json_simple.JsonException;
import com.github.cliftonlabs.json_simple.Jsoner;

public class SimpleParse {
    public static void main(String[] args) {
        try {
            List<SimplePokemon> pokemonList = getPokemon();
            pokemonList.stream().forEach(System.out::println);
        } catch (JsonException e) {
            e.printStackTrace();
        }
    }

    public static List<SimplePokemon> getPokemon() throws JsonException {
        List<SimplePokemon> results = new ArrayList<>();
        InputStream stream = SimpleParse.class.getClassLoader().getResourceAsStream("data.json");
        JsonArray deserialize = (JsonArray) Jsoner.deserialize(new InputStreamReader(stream));
        Mapper mapper = new DozerBeanMapper();
        deserialize.forEach((obj) -> {
            results.add(mapper.map(obj, SimplePokemon.class));
        });
        return results;
    }
}

SimplePokemon

package pokemon.parse;

import java.io.IOException;
import java.io.StringWriter;
import java.io.Writer;
import java.util.Arrays;

import com.github.cliftonlabs.json_simple.JsonObject;
import com.github.cliftonlabs.json_simple.Jsonable;

public class SimplePokemon implements Jsonable {
    private String dex;
    private String name;
    private String[] types;

    public String getDex() {
        return dex;
    }

    public void setDex(String dex) {
        this.dex = dex;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String[] getTypes() {
        return types;
    }

    public void setTypes(String[] types) {
        this.types = types;
    }

    @Override
    public String toJson() {
        final StringWriter writable = new StringWriter();
        try {
            this.toJson(writable);
        } catch (final IOException e) {
        }
        return writable.toString();
    }

    @Override
    public void toJson(Writer writer) throws IOException {
        final JsonObject json = new JsonObject();
        json.put("dex", this.getName());
        json.put("name", this.getName());
        json.put("types", this.getTypes());
        json.toJson(writer);
    }

    @Override
    public String toString() {
        return String.format("SimplePokemon [dex=%s, name=%s, types=%s]", dex, name, Arrays.toString(types));
    }
}

输出

SimplePokemon [dex=001, name=Bulbasaur, types=[Grass, Poison]]
SimplePokemon [dex=002, name=Ivysaur, types=[Grass, Poison]]

答案 2 :(得分:0)

您可以使用JSONArray。我个人的喜好是使用ArrayList。这就是我要做的。

 //import java.util.ArrayList;
 //import org.bson.Document;


 Document root= new Document();
 ArrayList rootTypes= new ArrayList();
 ArrayList rootFastMoves= new ArrayList();
 ArrayList rootChargeMoves= new ArrayList();
 ArrayList main= new ArrayList();


//Build your first JSON object       

 root.append("dex","001");

 root.append("name","Bulbasaur");

 rootTypes.add("Grass");

 rootTypes.add("Poison");

 root.append("attack",128);

 root.append("defense",118);

 root.append("HP",111);

 root.append("catchRate",0.2);

 root.append("fleeRate",0.1);

 root.append("candy",25);

 rootFastMoves.add("Vine Whip");

 rootFastMoves.add("Tackle");

 rootChargeMoves.add("Seed Bomb");

 rootChargeMoves.add("Sludge Bomb");

 rootChargeMoves.add("Power Whip");


 //bring your first JSON object together

 if (!rootTypes.isEmpty()){
 root.append("types",rootTypes);
 }
 if (!rootFastMoves.isEmpty()){
 root.append("fastMoves",rootFastMoves);
 }
 if (!rootChargeMoves.isEmpty()){
 root.append("chargeMoves",rootChargeMoves);
 }

 if (!root.isEmpty())
{
//You would do this for every JSON record.
main.append(root);
}