前言
在Android开发过程中,我们经常会遇到遍历整个集合的情况。但是在我们接收服务端返回数据json串的结构有种特别的情况,那就是对象种包含有一个集合,集合中装的数据类型又是自己,且数据层级不确定的情况,面对这种数据结构我们要怎样才能将其遍历完呢?
今天涉及内容:
涉及到的依赖
数据结构特点
拼接具有该特性的json串
该数据结构全遍历在Activty中的使用
效果图和项目结构图
MainHelper源码
先来波效果图
1.gif
一.涉及到的依赖
由于涉及到数据的组装与解析,所以会使用到json解析的问题。这里我采用的是Gson解析,则需要在app_module对应的build.gradle中添加gson依赖:
dependencies {
//gson
implementation 'com.google.code.gson:gson:2.8.5'
//其他代码省略
//......
}
二.数据结构特点
先来介绍下需要遍历的数据结构类型。
整个数据是一个对象集合。单个的对象中有些不同的属性,除此以外,该对象中会包含一个集合,该集合可能有数据,也可能没有。如果有数据的话,那么此集合中装的数据也是该对象本身。说起来有点绕,以Book为例说明,则简单的说来,我们就是要遍历一个集合中的所有Book对象,下面贴出Book代码:
public class Book {
private String name;
private int page;
private Listdata;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getPage() {
return page;
}
public void setPage(int page) {
this.page = page;
}
public List getData() {
return data;
}
public void setData(List data) {
this.data = data;
}
}
这里的难点是,Book中含有Listdata,而data中装载的还是Book,只要data不为null,我们就得一直遍历下去,直到获取所有的Book对象。
该数据结构最大的难点在于:Book 的数据层级未知,有多少则需要遍历多少。
三.拼接具有该特性的 json 串
为了详细讲解这个问题,我们需要组装一个该特色的Json串。
接下来我会组装一个Book的集合,里面有三个Book对象(以下Book对象以item表示),为了模拟item数据层级的不确定性,我会将每个item设置不同的层级结构。
3.1 第一个 item 特点
第一个 item层级为2,第二层有3个item,组装该item的代码如下:
/***
* 第一个book总item个数:1*3=3
*
* @return
*/
public Book getFirstItem(){
Book book=new Book();
book.setName("first,第一层");
book.setPage(1);
List firstList= new ArrayList();
for(int i=0;i<3;i++){
Book book2=new Book();
book2.setName("first"+i+",第二层");
book2.setPage(1*10+(i+1));
firstList.add(book2);
}
book.setData(firstList);
return book;
}
3.2 第二个 item 特点
第二个item我们设置数据层级为一层,比较简单。
/***
* 第二个book总item个数:1*1=1
*
* @return
*/
public Book getSecondItem(){
Book book=new Book();
book.setName("second,第一层");
book.setPage(2);
return book;
}
3.3 第三个 item 特点
第三个 item 会比较复杂。第一层item下面会有2个item,第二层下面有2个item,第三层下面有2个item,到第四层时,当item下标为1时,下面又有2个item。即第三个item共有5层。组装第三个 item的代码如下:
/***
* 第三个book总item个数:1*2*2*(1+1*2)=12
*
* @return
*/
public Book getThirdItem(){
Book book=new Book();
book.setName("third,第一层");
book.setPage(3);
ListthirdList= new ArrayList();
for(int i=0;i<2;i++){
Book book2=new Book();
book2.setName("third"+i+",第二层");
book2.setPage(3*10+(i+1));
Listthird2List= new ArrayList();
for(int j=0;j<2;j++) {
Book book3 = new Book();
book3.setName("third"+i + j + ",第三层");
book3.setPage(3 * 100 + (j+1));
Listthird3List= new ArrayList();
for(int k=0;k<2;k++){
Book book4 = new Book();
book4.setName("third" + i + j +k + ",第四层");
book4.setPage(3 * 1000 + (k+1));
if(k==1){
Listthird4List= new ArrayList();
for(int f=0;f<2;f++){
Book book5 = new Book();
book5.setName("third" +i + j +k + f + ",第五层");
book5.setPage(3 * 10000 + (f+1));
third4List.add(book5);
}
book4.setData(third4List);
}
third3List.add(book4);
}
book3.setData(third3List);
third2List.add(book3);
}
book2.setData(third2List);
thirdList.add(book2);
}
book.setData(thirdList);
return book;
}
然后将这三个item添加到bookList中:
List bookList = new ArrayList<>();
//第一个item
Book firstItem = mainHelper.getFirstItem();
bookList.add(firstItem);
//第二个item
Book secondItem = mainHelper.getSecondItem();
bookList.add(secondItem);
//第三个item
Book thirdItem = mainHelper.getThirdItem();
bookList.add(thirdItem);
//将list转json串
String jsonString = mainHelper.BeanToString(bookList);
LogUtil.i("jsonString:"+jsonString);
生成的json结构如下图
数据.png
结构.png
以上只是截取部分数据图,具体的大家可以查看运行打印的json串:
[{"data":[{"name":"first0,第二层","page":11},{"name":"first1,第二层","page":12},{"name":"first2,第二层","page":13}],"name":"first,第一层","page":1},{"name":"second,第一层","page":2},{"data":[{"data":[{"data":[{"name":"third000,第四层","page":3001},{"data":[{"name":"third0010,第五层","page":30001},{"name":"third0011,第五层","page":30002}],"name":"third001,第四层","page":3002}],"name":"third00,第三层","page":301},{"data":[{"name":"third010,第四层","page":3001},{"data":[{"name":"third0110,第五层","page":30001},{"name":"third0111,第五层","page":30002}],"name":"third011,第四层","page":3002}],"name":"third01,第三层","page":302}],"name":"third0,第二层","page":31},{"data":[{"data":[{"name":"third100,第四层","page":3001},{"data":[{"name":"third1010,第五层","page":30001},{"name":"third1011,第五层","page":30002}],"name":"third101,第四层","page":3002}],"name":"third10,第三层","page":301},{"data":[{"name":"third110,第四层","page":3001},{"data":[{"name":"third1110,第五层","page":30001},{"name":"third1111,第五层","page":30002}],"name":"third111,第四层","page":3002}],"name":"third11,第三层","page":302}],"name":"third1,第二层","page":32}],"name":"third,第一层","page":3}]
四.该数据结构全遍历在Activty中的使用
数据结构已经组装完成,则我们需要遍历的是bookList中的所有Book对象。我们很容易想到的是用递归思想遍历完所有book,这里为了使用方便,我已经将模拟数据的组装及递归遍历的方法都写在了MainHelper类中,下面就来看看MainHelper遍历bookList中的所有Book对象在MainActivity中的使用吧。
public class MainActivity extends AppCompatActivity {
private TextView mTv;
private Button mBtn;
private MainHelper mainHelper;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
LogUtil.setDebug(true);
initView();
initData();
setListener();
}
private void initView() {
mTv = findViewById(R.id.tv);
mBtn = findViewById(R.id.btn);
}
private void initData() {
mainHelper=new MainHelper();
}
private void setListener() {
mBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
createData();
}
});
}
private void createData() {
List bookList = new ArrayList<>();
//第一个item
Book firstItem = mainHelper.getFirstItem();
bookList.add(firstItem);
//第二个item
Book secondItem = mainHelper.getSecondItem();
bookList.add(secondItem);
//第三个item
Book thirdItem = mainHelper.getThirdItem();
bookList.add(thirdItem);
//将list转json串
String jsonString = mainHelper.BeanToString(bookList);
LogUtil.i("jsonString:"+jsonString);
//遍历所有item
List totalList=mainHelper.getTotalList(bookList);
StringBuffer buffer=new StringBuffer();
LogUtil.i("=======size=="+totalList.size());
buffer.append("集合总个数: size="+totalList.size()+"\n");
for(int i=0;i
LogUtil.i("=====i="+i+" bookName="+totalList.get(i).getName());
buffer.append(totalList.get(i).getName()+"\n");
}
mTv.setText(buffer.toString());
}
}
综合前面3个item的组装分析,我们可以发现bookList中总共包含的book个数为:
1*3+1*1+1*2*2*(1+1*2)=16,最后遍历totalList发现其个数即为16,说明算法正确。
五.效果图和项目结构图
效果图.gif
项目结构图.png
六.MainHelper源码
下面贴出MainHelper源码: