美文网首页
Android遍历对象包含自身集合的算法

Android遍历对象包含自身集合的算法

作者: 奔跑的佩恩 | 来源:发表于2020-11-22 14:34 被阅读0次

    前言

    Android开发过程中,我们经常会遇到遍历整个集合的情况。但是在我们接收服务端返回数据json串的结构有种特别的情况,那就是对象种包含有一个集合,集合中装的数据类型又是自己,且数据层级不确定的情况,面对这种数据结构我们要怎样才能将其遍历完呢?

    今天涉及内容:

    1. 涉及到的依赖
    2. 数据结构特点
    3. 拼接具有该特性的json
    4. 该数据结构全遍历在Activty中的使用
    5. 效果图和项目结构图
    6. 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 List<Book>data;
    
        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<Book> getData() {
            return data;
        }
    
        public void setData(List<Book> data) {
            this.data = data;
        }
    
    }
    

    这里的难点是,Book中含有List<Book>data,而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<Book> 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);
            List<Book>thirdList= new ArrayList();
            for(int i=0;i<2;i++){
                Book book2=new Book();
                book2.setName("third"+i+",第二层");
                book2.setPage(3*10+(i+1));
                List<Book>third2List= new ArrayList();
                for(int j=0;j<2;j++) {
                    Book book3 = new Book();
                    book3.setName("third"+i + j + ",第三层");
                    book3.setPage(3 * 100 + (j+1));
                    List<Book>third3List= 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){
                            List<Book>third4List= 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<Book> 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<Book> 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<Book> totalList=mainHelper.getTotalList(bookList);
    
            StringBuffer buffer=new StringBuffer();
            LogUtil.i("=======size=="+totalList.size());
            buffer.append("集合总个数: size="+totalList.size()+"\n");
            for(int i=0;i<totalList.size();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源码:

    相关文章

      网友评论

          本文标题:Android遍历对象包含自身集合的算法

          本文链接:https://www.haomeiwen.com/subject/ajkeiktx.html