Android基础 平面数据与父子关系的数据转换

写在前面: 对于父子关系的数据一般在做城市的三级联动的时候,可能会将数据做成此类形的数据。但是有时候后台返回的数据却是平面的,导致这种原因的问题是因为,在数据库存储的时候,只能是按照平面的数据去存储,然后再根据他们的父id去处理他们的层级关系。

好了说了一些无关紧要的话,然后开始今天的主要内容,我会将今天讲解的分为以下几点:

  1. 平面数据转换为父子关系的数据
  2. 从本地读取大文件,并进行处理

好,话不多说,直接开始


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大功告成

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值