有效的方法来解析文件以获取List ...?

时间:2010-11-04 17:00:42

标签: java groovy

ID Name Department Salary Designation
---------------------------------------
1  Kent Engineering 100000$ senior-engineer  
2  Smith null       50,000$ administrator

这些是我拥有的大文件的记录。我需要解析这个文件来检索薪水和指定。密钥必须是ID,Name,Department,如果失败则使用ID,Name .. 我只能使用Java / groovy来做到这一点......我如何得到<Salary,Designation> ...?

因为我只能使用java / groovy

,所以最有效的方法是grep它

5 个答案:

答案 0 :(得分:1)

创建一个BufferedReader,这将允许您一次读取一行文件。然后在每一行上调用split("[\\\s]"),这将按空格分割。

您可能还需要按工资字段,以便将其解析为数字。

答案 1 :(得分:1)

在空白处拆分每一行。

scala> val a = "1  Kent Engineering 100000$ senior-engineer"
a: java.lang.String = 1  Kent Engineering 100000$ senior-engineer

scala> a.split("\\s+")
res1: Array[java.lang.String] = Array(1, Kent, Engineering, 100000$, senior-engineer)

然后获取原始字符串值并解析它们。例如。将50,000美元转换为50000:

double salary = Double.parseDouble(array[SALARY_INDEX].replaceAll("[$,]",""))


java.lang.Double.parseDouble("50,000$".replaceAll("[$,]",""))
res6: Double = 50000.0

答案 2 :(得分:0)

您可以将文件解析为HashMap并在需要时随身携带。

它的前期成本很高,但是如果你要经常使用它,那么它是有道理的。

然后创建键和值对象。请务必覆盖密钥的equals

public class Key{
    int id;
    String name;

    @Override
    public boolean equals(Object o){...}
}

答案 3 :(得分:0)

我假设您已经知道如何使用BufferedReader逐行读取文件,因为这是此类事情的明显先决条件 - 如果不是,请大喊。

关键是你没有指定的东西。什么,完全,是数据的格式 - 特别是,确定一个字段结束而另一个字段开始的确切规则是什么?

如果数据由制表符分隔(并且数据中禁止出现所述字符,即使转义),那么解决方案很简单:

// Ignoring general error handling and EOF-checking here
final String line = bufferedReader.readLine();
final String[] fields = line.split("\t");

现在您有一个包含该行字段的数组,因此只需查找fields[3]fields[4]

如果分隔符是“任意数量的空格”,并且完全不允许使用空格,那么您的状态正好相同,正则表达式为line.split(" *")

在更复杂的情况下,包括允许在转义或引用时显示分隔符的情况,您可能最好只是逐个字符地逐行迭代并根据分隔符规则手动构建字段集。

答案 4 :(得分:0)

有一点Guava library,解决方案简单而优雅。我们可以通过客观化关键,处理错误等来改进下面的代码,但你可以自己做到

import java.io.File;
import java.io.IOException;
import java.util.Iterator;
import java.util.Map;

import com.google.common.base.CharMatcher;
import com.google.common.base.Charsets;
import com.google.common.base.Joiner;
import com.google.common.base.Splitter;
import com.google.common.collect.Maps;
import com.google.common.io.Files;
import com.google.common.io.LineProcessor;

public class FileProcessor
{

    private static final Splitter SPLITTER = Splitter.on(CharMatcher.WHITESPACE);

    private static final Joiner KEY_BUILDER = Joiner.on("_").skipNulls();

    @SuppressWarnings("unchecked")
    public static void main(final String[] args) throws IOException
    {
        Map<String, SalaryAndDesignation> result = Files.readLines(new File("c:/1.txt"), Charsets.ISO_8859_1, new LineProcessor() {

            private final Map<String, SalaryAndDesignation> result = Maps.newHashMap();

            public Object getResult()
            {
                return result;
            }

            public boolean processLine(final String line) throws IOException
            {
                Iterator<String> columns = SPLITTER.split(line).iterator();
                String id = columns.next();
                String name = columns.next();
                String dept = columns.next();

                String key = KEY_BUILDER.join(id, name, "null".equals(dept) ? null : dept);

                result.put(key, new SalaryAndDesignation(columns.next(), columns.next()));
                return true;
            }
        });
        System.out.println(result.size());
    }

    final static class SalaryAndDesignation
    {
        String salary;

        String designation;

        public SalaryAndDesignation(final String salary, final String designation)
        {
            super();
            this.salary = salary;
            this.designation = designation;
        }

    }
}

我在下面的示例(copy/pasted from here)中看到使用较少代码的groovy结果但从未使用过它

new File("simple.tab").withReader{r->
    line = r.readLine();
    println "first line: $line"
    r.splitEachLine("\t"){fields->
            println "fields on line: $fields"
    }  
}