首页 > PHP资讯 > JAVA培训 > 你不知道的5个Java有用的工具(3)

你不知道的5个Java有用的工具(3)

JAVA培训

3. Scanner

有无数 Java 工具能帮助您构建解析器,很多函数语言已成功构建解析器函数库(解析器选择器)。但如果要解析的是逗号分隔值文件,或空格分隔文本文件,又怎么办呢?大多数工具用在此处就过于隆重了,而 String.split() 又不够。(对于正则表达式,请记住一句老话:“ 您有一个问题,用正则表达式解决。那您就有两个问题了。”)

Java 平台的 Scanner 类会是这些类中您最好的选择。以轻量级文本解析器为目标,Scanner 提供了一个相对简单的 API,用于提取结构化文本,并放入强类型的部分。想象一下,如果您愿意,一组类似 DSL 的命令(源自 Terry Pratchett Discworld 小说)排列在文本文件中,如清单 7:

清单 7. Igor 的任务


      
fetch 1 head  
fetch 3 eye  
fetch 1 foot  
attach foot to head  
attach eye to head  
admire  

您,或者是本例中称为 Igor的私仆,能轻松使用 Scanner 解析这组违法命令,如清单 8 所示:

清单 8. Igor 的任务,由 Scanner 解析


      
import java.io.*;  
import java.util.*;  

public class Igor  
    implements IPersonalServant  
{  
    public boolean can(String cmd)  
    {  
        if (cmd.equals("fetch body parts"))  
            return true;  
        if (cmd.equals("attach body parts"))  
            return true;  
        else  
            return false;  
    }  
    public void process(File commandFile)  
        throws FileNotFoundException  
    {  
        Scanner scanner = new Scanner(commandFile);  
        // Commands come in a verb/number/noun or verb form  
        while (scanner.hasNext())  
        {  
            String verb = scanner.next();  
            if (verb.equals("fetch"))  
            {  
                int num = scanner.nextInt();  
                String type = scanner.next();  
                fetch (num, type);  
            }  
            else if (verb.equals("attach"))  
            {  
                String item = scanner.next();  
                String to = scanner.next();  
                String target = scanner.next();  
                attach(item, target);  
            }  
            else if (verb.equals("admire"))  
            {  
                admire();  
            }  
            else  
            {  
                System.out.println("I don't know how to "   
                    + verb + ", marthter.");  
            }  
        }  
    }  
      
    public void fetch(int number, String type)  
    {  
        if (parts.get(type) == null)  
        {  
            System.out.println("Fetching " + number + " "   
                + type + (number > 1 ? "s" : "") + ", marthter!");  
            parts.put(type, number);  
        }  
        else  
        {  
            System.out.println("Fetching " + number + " more "   
                + type + (number > 1 ? "s" : "") + ", marthter!");  
            Integer currentTotal = parts.get(type);  
            parts.put(type, currentTotal + number);  
        }  
        System.out.println("We now have " + parts.toString());  
    }  
      
    public void attach(String item, String target)  
    {  
        System.out.println("Attaching the " + item + " to the " +  
            target + ", marthter!");  
    }  
      
    public void admire()  
    {  
        System.out.println("It'th quite the creathion, marthter");  
    }  
      
    private Map<String, Integer> parts = new HashMap<String, Integer>();  
}  

假设 Igor 已在 ServantLoader 中注册,可以很方便地将 can() 调用改得更实用,并重用前面的 Servant 代码,如清单 9 所示:

清单 9. Igor 做了什么


import java.io.*;  
import java.util.*;  

public class Servant  
{  
    public static void main(String[] args)  
        throws IOException  
    {  
        ServiceLoader<IPersonalServant> servantLoader =   
            ServiceLoader.load(IPersonalServant.class);  

        IPersonalServant i = null;  
        for (IPersonalServant ii : servantLoader)  
            if (ii.can("fetch body parts"))  
                i = ii;  

        if (i == null)  
            throw new IllegalArgumentException("No suitable servant found");  
          
        for (String arg : args)  
        {  
            i.process(new File(arg));  
        }  
    }  
}  

真正 DSL 实现显然不会仅仅打印到标准输出流。我把追踪哪些部分、跟随哪些部分的细节留待给您(当然,还有忠诚的 Igor)。

常州java培训

本文由欣才IT学院整理发布,未经许可,禁止转载。