写在前面: 对于父子关系的数据一般在做城市的三级联动的时候,可能会将数据做成此类形的数据。但是有时候后台返回的数据却是平面的,导致这种原因的问题是因为,在数据库存储的时候,只能是按照平面的数据去存储,然后再根据他们的父id去处理他们的层级关系。
好了说了一些无关紧要的话,然后开始今天的主要内容,我会将今天讲解的分为以下几点:
- 平面数据转换为父子关系的数据
- 从本地读取大文件,并进行处理
好,话不多说,直接开始
1、平面数据转换为父子关系的数据
首先会用到一个实体类的对象,后面的本地大文件的读取也会用到这个实体类文件
public class Address {
private String region_id;//当前的地址对应的id
private String parent_id;///当前地址对应父地址的id
private String region_name;//当前地址的名称
private List<Address> child;//当前地址所包含的子地址,这个参数其实不是后台返回的数据
public Address(String id, String value,String paid) {
super();
this.region_id = id;
this.parent_id = paid;
this.region_name = value;
}
public List<Address> getChild() {
return child;
}
public void setChild(List<Address> child) {
this.child = child;
}
public String getRegion_id() {
return region_id;
}
public void setRegion_id(String region_id) {
this.region_id = region_id;
}
public String getParent_id() {
return parent_id;
}
public void setParent_id(String parent_id) {
this.parent_id = parent_id;
}
public String getRegion_name() {
return region_name;
}
public void setRegion_name(String region_name) {
this.region_name = region_name;
}
@Override
public String toString() {
return "Address [region_id=" + region_id + ", parent_id=" + parent_id + ", region_name=" + region_name
+ ", child=" + child + "]";
}
}
好,话不多说直接开始:
1、为了模拟平面的数据,我们先做一下数据的初始化:
private List<Address> readData(){
List<Address> aList = new ArrayList<>();
aList.add(new Address("1", "山东省", "0"));
aList.add(new Address("2", "江苏省", "0"));
aList.add(new Address("3", "浙江省", "0"));
aList.add(new Address("4", "黑龙江省", "0"));
aList.add(new Address("5", "济宁市", "1"));
aList.add(new Address("6", "济南市", "1"));
aList.add(new Address("7", "菏泽市", "1"));
aList.add(new Address("8", "南京市", "2"));
aList.add(new Address("9", "杭州市", "3"));
aList.add(new Address("10", "哈尔滨市", "4"));
aList.add(new Address("11", "xx县", "5"));
aList.add(new Address("12", "市中区", "6"));
return aList;
}
数据源有了,然后开始处理数据:
2、第一次for
循环先创建一个List
集合,这个集合将会最终转换为我们要使用的数据,然后创建一个TreeMap
,这个Map 的主要目的就是为了将数据源中所有的地区id
取出作为key
,这个后面转换的时候会用到。
3、第二次for
循环,通过判断父id
如果是最顶层的,比如说是省,一般他们的父id
都是0(有的也会是1,根据情况而定)。将父id
为以上情况的加入到我们的dataList
中,不符合上述情况的,再将当前地区的父id
取出,从我们的Map
中取出对应地区的对象。判断他们的子类型是否为空,如果为空就创建一个新的子List
集合,如果不为空就直接将当前的地区加入到这个父地区的子集合中。
好经过以上的两次循环,就可以完美将平面数据转换为父子关系的数据了。
List<Address> addreessList = readData();
List<Address> dataList = new ArrayList<>();
Map<String,Address> keyMap = new TreeMap<String,Address>();
for (Address address : addreessList) {
keyMap.put(address.getRegion_id(), address);
}
for (Address address : addreessList) {
if (address.getParent_id().equals("0")) {
//如果符合这种情况,说明它就是最顶层的,直接放到我们最终的数据集合中就ok了
dataList.add(address);
}else{//不符合的话,就说明肯定是子对象
Address parentBean = keyMap.get(address.getParent_id());
List<Address> childList = parentBean.getChild();
if (childList!=null) {
childList.add(address);
}else{
childList = new ArrayList<>();
childList.add(address);
parentBean.setChild(childList);
}
}
}
System.out.println(dataList.toString());//大家可以复制下代码看看结果,因为截图比较难看,就不贴了
2. 从本地读取大文件,并进行处理
工欲善其事必先利其器,读取本地大文件的话,推荐一个第三方的框架,会比较快,当然你如果觉得不喜欢用第三方框架,非得自己写的话,Android本身也是提供了相应的Api,只不过数据都要自己一步一步的去解析。个人还是推荐使用第三方的框架。
好的吹了半天的第三方框架,那他是谁的呢。它就是我们阿里巴巴的FastJson
传送门对于本地大文件的读取,效率是非常高的,而且不会出现内存溢出的问题。然后我根据这个框架封装了一个小的工具类
本地文件可以这里去下载本地文件
/**
* 解析本地的JSON数据
*
* @param context 环境变量
* @param fileName 文件名称
* @return 返回传入类型的List集合
*/
public static <T> List<T> getJsonArray(Context context, String fileName, Class<T> clazz) throws IOException {
InputStream is = context.getAssets().open(fileName);
return getJsonArray(is, "UTF-8", clazz);
}
public static <T> List<T> getJsonArray(InputStream is, String stringCoded, Class<T> clazz) throws IOException {
List<T> array = new ArrayList<T>();
JSONReader jsonReader = new JSONReader((new InputStreamReader(is, stringCoded)));
jsonReader.startArray();
while (jsonReader.hasNext()) {
T value = jsonReader.readObject(clazz);
array.add(value);
}
jsonReader.endArray();
jsonReader.close();
return array;
}
/**
* 解析本地的JSON数据
*
* @param context 环境变量
* @param fileName 文件名称
* @return 返回传入的相应类型
*/
public static <T> T getJsonObject(Context context, String fileName, Class<T> clazz) throws IOException {
InputStream is = context.getAssets().open(fileName);
return getJsonObject(is, "UTF-8", clazz);
}
public static <T> T getJsonObject(InputStream is, String stringCoded, Class<T> clazz) throws IOException {
T value = null;
JSONReader jsonReader = new JSONReader(new InputStreamReader(is, stringCoded));
jsonReader.startObject();
value = jsonReader.readObject(clazz);
jsonReader.endObject();
jsonReader.close();
return value;
}
具体的用法
public List<Address> readAddressInfo(Context context) {
List<Address> addressList;
try {
addressList = JsonFormFileUtils.getJsonArray(context, "hld_area.json", Address.class);
} catch (IOException e) {
e.printStackTrace();
addressList = new ArrayList<>();
}
return addressList;
}
ok大功告成