Java 如何使用GSON将大型JSON文件分割成块并进行排序
我有一个巨大的JSON文件名为something.JSON。文件大小为20MB。我正在和格森一起读这篇文章。它是在标准安卓Nexus 5X上读取的 Json的示例:Java 如何使用GSON将大型JSON文件分割成块并进行排序,java,json,sorting,parsing,gson,Java,Json,Sorting,Parsing,Gson,我有一个巨大的JSON文件名为something.JSON。文件大小为20MB。我正在和格森一起读这篇文章。它是在标准安卓Nexus 5X上读取的 Json的示例: [ {"country":"UA","name":"Hurzuf","_id":707860,"coord":{"lon":34.283333,"lat":44.549999}}, {"country":"UA","name":"Il’ichëvka","_id":707716,"coord":{"lon":34.3
[
{"country":"UA","name":"Hurzuf","_id":707860,"coord":{"lon":34.283333,"lat":44.549999}},
{"country":"UA","name":"Il’ichëvka","_id":707716,"coord":{"lon":34.383331,"lat":44.666668}},
{"country":"BG","name":"Rastnik","_id":727762,"coord":{"lon":25.283331,"lat":41.400002}}
...
]
代码:
它需要从Android API 16运行到最新版本
我需要把这个读给McCities,然后按城市名称的字母顺序排序。现在这需要3分钟,必须在10秒内完成。我的方法是将json文件分成10个较小的块,读入,连接并排序
所以我的问题是:如何将文件分成更小的块,这是解决这个问题的正确方法吗
链接到文件:我基本上从来没有做过Android本身的编码,但我有一些注释和想法供您参考,因为这是纯Java。 您的读者在阅读每一个元素时都做了大量的工作。 首先,您不需要每次需要时都创建
Gson
:
- 它是不可变的,线程安全的
- 这是相对昂贵的创建
- 实例化一个
实例也会命中堆,需要花费更多的时间来执行,然后进行垃圾收集Gson
最后一级城市{
@SerializedName(“\u id”)
最终int id;
@序列化名称(“国家”)
最终字符串国家;
@序列化名称(“名称”)
最后的字符串名;
@序列化名称(“协调”)
最终坐标;
私人城市(最终整数id、最终字符串国家、最终字符串名称、最终坐标){
this.id=id;
这个国家=国家;
this.name=名称;
这个。坐标=坐标;
}
静态城市(最终整数id、最终字符串国家、最终字符串名称、最终坐标){
返回新城市(id、国家、名称、坐标);
}
@凌驾
公共布尔等于(最终对象o){
if(this==o){
返回true;
}
如果(o==null | | getClass()!=o.getClass()){
返回false;
}
最终城市,即=(城市)o;
return id==that.id;
}
@凌驾
公共int hashCode(){
返回id;
}
@抑制警告(“恒定条件”)
公共静态int compareByName(最终城市1,最终城市2){
返回city1.name.compareTo(city2.name);
}
}
Coordinates.java
最终类坐标{
@序列化名称(“lat”)
最终双纬度;
@序列化名称(“lon”)
最终双经度;
专用坐标(最终双纬度、最终双经度){
这个。纬度=纬度;
这个经度=经度;
}
静态坐标(最终双纬度、最终双经度){
返回新坐标(纬度、经度);
}
@凌驾
公共布尔等于(最终对象o){
if(this==o){
返回true;
}
如果(o==null | | getClass()!=o.getClass()){
返回false;
}
最终坐标=(坐标)o;
返回Double.compare(即纬度,纬度)==0
&&比较(即经度,经度)==0;
}
@凌驾
公共int hashCode(){
最终长纬度EBITs=双倍。双倍至长位(纬度);
最终长纵向比特率=双精度。双精度长比特率(经度);
最终int latitudeHash=(int)(latitudeBits^ latitudeBits>>>32);
最终int longitudeHash=(int)(longitudeBits^ longitudeBits>>>32);
返回31*latitudeHash+LongtudeHash;
}
}
测试基础设施
ITest.java
接口测试{
@非空
默认字符串getName(){
返回getClass().getSimpleName();
}
@非空
集合测试(@Nonnull JsonReader-JsonReader)
抛出IOException;
}
主要的
publicstaticvoidmain(最终字符串…args)
抛出IOException{
最终Iterable测试=不可变列表(
FirstTest.get(),
ReadAsWholeListTest.get(),
ReadAsWholeTreeSetTest.get(),
ReadJsonStreamIntoListTest.get(),
readjsonstreamnotreesettest.get(),
ReadJsonStreamIntoListChunksTest.get()
);
对于(int i=0;i<3;i++){
用于(最终ITest测试:测试){
try(final-ZipInputStream-ZipInputStream=new-ZipInputStream(Resources.getPackageResourceInputStream(Q49273660.class,“cities.json.zip”)){
for(ZipEntry-ZipEntry=zipInputStream.getnextery();ZipEntry!=null;ZipEntry=zipInputStream.getnextery()){
if(zipEntry.getName().equals(“cities.json”)){
final JsonReader JsonReader=new JsonReader(new InputStreamReader(zipInputStream));//不关闭
System.out.printf(“%1$35s:”,test.getName());
final Stopwatch Stopwatch=Stopwatch.createStarted();
最终收集城市=test.test(jsonReader);
System.out.printf(“以%d毫秒为单位,包含%d个元素\n”、stopwatch.appead(TimeUnit.ms)、cities.size());
资产排序(城市,城市::compareByName);
}
}
@Override
protected ArrayList<City> doInBackground(File... files) {
ArrayList<City> cities = new ArrayList<>();
try {
InputStream is = new FileInputStream(files[0]);
JsonReader reader = new JsonReader(new InputStreamReader(is, "UTF-8"));
reader.beginArray();
while (reader.hasNext()) {
City city = new Gson().fromJson(reader, City.class);
cities.add(city);
}
reader.endArray();
reader.close();
} catch (Exception e) {
mResult.onFinish(cities, e.getMessage());
}
Collections.sort(cities, (o1, o2) -> o1.getName().compareTo(o2.getName()));
mResult.onFinish(cities, CityService.SUCCESS);
return cities;
}
com.google.code.gson:gson:2.8.0
final class ReadAsWholeTreeSetTest
implements ITest {
private static final ITest instance = new ReadAsWholeTreeSetTest();
private ReadAsWholeTreeSetTest() {
}
static ITest get() {
return instance;
}
@SuppressWarnings({ "rawtypes", "unchecked" })
private static final TypeToken<TreeSet<?>> rawTreeSetType = (TypeToken) TypeToken.get(TreeSet.class);
private static final Map<Type, Comparator<?>> comparatorsRegistry = ImmutableMap.of(
City.class, (Comparator<City>) City::compareByName
);
private static final Gson gson = new GsonBuilder()
.registerTypeAdapterFactory(new TypeAdapterFactory() {
@Override
public <T> TypeAdapter<T> create(final Gson gson, final TypeToken<T> typeToken) {
if ( !TreeSet.class.isAssignableFrom(typeToken.getRawType()) ) {
return null;
}
final Type elementType = ((ParameterizedType) typeToken.getType()).getActualTypeArguments()[0];
@SuppressWarnings({ "rawtypes", "unchecked" })
final Comparator<Object> comparator = (Comparator) comparatorsRegistry.get(elementType);
if ( comparator == null ) {
return null;
}
final TypeAdapter<TreeSet<?>> originalTreeSetTypeAdapter = gson.getDelegateAdapter(this, rawTreeSetType);
final TypeAdapter<?> originalElementTypeAdapter = gson.getDelegateAdapter(this, TypeToken.get(elementType));
final TypeAdapter<TreeSet<Object>> treeSetTypeAdapter = new TypeAdapter<TreeSet<Object>>() {
@Override
public void write(final JsonWriter jsonWriter, final TreeSet<Object> treeSet)
throws IOException {
originalTreeSetTypeAdapter.write(jsonWriter, treeSet);
}
@Override
public TreeSet<Object> read(final JsonReader jsonReader)
throws IOException {
jsonReader.beginArray();
final TreeSet<Object> elements = new TreeSet<>(comparator);
while ( jsonReader.hasNext() ) {
final Object element = originalElementTypeAdapter.read(jsonReader);
elements.add(element);
}
return elements;
}
}.nullSafe();
@SuppressWarnings({ "rawtypes", "unchecked" })
final TypeAdapter<T> castTreeSetTypeAdapter = (TypeAdapter<T>) treeSetTypeAdapter;
return castTreeSetTypeAdapter;
}
})
.create();
private static final Type citiesSetType = new TypeToken<TreeSet<City>>() {
}.getType();
@Nonnull
@Override
public Set<City> test(@Nonnull final JsonReader jsonReader) {
return gson.fromJson(jsonReader, citiesSetType);
}
}
FirstTest : in 5797 ms with 209557 elements
ReadAsWholeListTest : in 796 ms with 209557 elements
ReadAsWholeTreeSetTest : in 733 ms with 162006 elements
ReadJsonStreamIntoListTest : in 461 ms with 209557 elements
ReadJsonStreamIntoTreeSetTest : in 452 ms with 162006 elements
ReadJsonStreamIntoListChunksTest : in 607 ms with 209557 elements
--------------------
FirstTest : in 3396 ms with 209557 elements
ReadAsWholeListTest : in 493 ms with 209557 elements
ReadAsWholeTreeSetTest : in 520 ms with 162006 elements
ReadJsonStreamIntoListTest : in 385 ms with 209557 elements
ReadJsonStreamIntoTreeSetTest : in 377 ms with 162006 elements
ReadJsonStreamIntoListChunksTest : in 540 ms with 209557 elements
--------------------
FirstTest : in 3448 ms with 209557 elements
ReadAsWholeListTest : in 429 ms with 209557 elements
ReadAsWholeTreeSetTest : in 421 ms with 162006 elements
ReadJsonStreamIntoListTest : in 400 ms with 209557 elements
ReadJsonStreamIntoTreeSetTest : in 385 ms with 162006 elements
ReadJsonStreamIntoListChunksTest : in 480 ms with 209557 elements
--------------------