码迷,mamicode.com
首页 > 其他好文 > 详细

迭代器与组合模式

时间:2016-05-15 11:05:08      阅读:258      评论:0      收藏:0      [点我收藏+]

标签:

迭代器(Iterator)与组合模式(Composite)

   迭代器是我们经常接触的东西,当然,我们更习惯使用的是类似这样的代码:

        String[] arr = new String[]{"one", "two", "three"};
        for (String num : arr) {
            System.out.println(num);
        }

  

  而完整的迭代器是这样子的:

 

        List<String> numberList = new ArrayList<String>();
        numberList.add("one");
        numberList.add("two");
        numberList.add("three");
        Iterator<String> iterator = numberList.iterator();
        while (iterator.hasNext()) {
            System.out.println(iterator.next());
        }

 

  我们打开List接口的实现类ArrayList,可以发现里面有个私有类,其实就是实现了迭代器接口的一个类。

技术分享

 

  那么我们为什么要使用迭代器,或者在什么场景下去使用它?迭代器意图在于提供一个统一的遍历回调入口,有点像是这样子:

 

package top.gabin.design.iterator;

import org.junit.Test;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

/**
 * Class description
 * @author linjiabin on  16/5/15
 */
public class IteratorDemo {

    @Test
    public void testDemo() {
        List<String> numberList = new ArrayList<String>();
        numberList.add("one");
        numberList.add("two");
        numberList.add("three");
        printListForUpdateCase(numberList, new DealString() {
            public String updateCase(String content) {
                if (content == null) {
                    return null;
                }
                return content.toUpperCase();
            }
        });
    }

    private void printListForUpdateCase(List<String> list, DealString dealString) {
        Iterator<String> iterator = list.iterator();
        while (iterator.hasNext()) {
            String next = iterator.next();
            System.out.println(dealString.updateCase(next));
        }
    }

    private interface DealString {
        String updateCase(String content);
    }

}

 

  提供一个统一的遍历入口的意义在于,你不再需要知道这个数组或者集合容器的结构,换言之,如果没有迭代器的存在,你将需要使用类似这样的代码:

        List<String> numberList = new ArrayList<String>();
        numberList.add("one");
        numberList.add("two");
        numberList.add("three");

        for (int i = 0; i < numberList.size(); i++) {
            System.out.println(numberList.get(i));
        }

  首先你需要知道这个集合的长度获取方法size(),其次你需要知道根据索引获取元素的方法get(index)。相比而言,Iterator是不是简单了许多?

 

 

  组合模式:允许你将对象组织成树形结构,表现为"整体/部分"的层级结构,允许用户使用一致的方式调用个别对象和组合对象。

 

  我们抓住关键的词:树形结构,好吧,这是一个经常需要用到递归的结构。树形结构一般分为根(root)、树节点、叶节点,根有点像是Linux系统中的根目录,树节点则是文件夹,那么对了,叶节点则是文件。假设我们现在需要遍历所有文件名称(包含文件夹的名称)。

 

  

package top.gabin.design.composite;

import java.io.File;

/**
 *
 * @author linjiabin on  16/5/15
 */
public class AccessDirectory {

    /**
     * 遍历打印文件
     * @param file
     */
    public void printListFile(File file) {
        if (file.isDirectory()) {
            File[] files = file.listFiles();
            for (File f : files) {
                printListFile(f);
            }
        } else {
            System.out.println(file.getName());
        }
    }

}

测试类代码:

package top.gabin.design.composite;

import org.junit.Test;

import java.io.File;

/**
 * Class description
 *
 * @author linjiabin on  16/5/15
 */
public class TestAccessDirectory {
    @Test
    public void testPrintDirectory() {
        File file = new File("/data/mall/mysql");
        new AccessDirectory().printListFile(file);
    }
}

 

打印出来的结果是:

.DS_Store
.DS_Store
mysql.000001
mysql.000002
mysql.000003
mysql.000004
mysql.000005
mysql.000006
mysql.000007
mysql.000008
mysql.000009
mysql.000010
mysql.000011
mysql.000012
mysql.000013
mysql.000014
mysql.000015
mysql.000016
mysql.000017
mysql.000018
mysql.000019
mysql.000020
mysql.index
roma.log
slow.log

 

当然这不是关键,而是正如你所看到的一样,文件夹的类型也是File,文件的类型也是File,然后你不可能在文件的对象后面调用listFile方法,不是吗?这就是组合模式的妙处,你可以将这两者在递归访问的过程中,调用几乎相同的代码(如果你不想知道它是文件还是文件夹的情况下)。

迭代器与组合模式

标签:

原文地址:http://www.cnblogs.com/gabin/p/5494719.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!