3

假设我有一个String类型为键、ArrayList类型为值的哈希图,例如{"value1"=["one","three","five"], "value2"=["two","four","six"]}“value1”和“value2”是键。我想以以下格式编写上述哈希图数据。(这样我就可以在 excel 中读取 csv 文件)

value1,value2
one,two
three,four
five,six

我的想法是编写第一个键及其值如下

value1
one
three
five

然后我正在考虑在RandomAccessFile课堂上使用 seek 方法返回到第 1 行并再次写入第二个键及其值。但是,我无法完成此任务,因为 seek 函数会获取整个文件中字符串的长度并在其后写入新字符串。虽然我希望指针跳转到第一行并附加字符串。有一个更好的方法吗?。一个简单的例子将不胜感激。

谢谢

4

4 回答 4

2

为什么不能只使用 4 个字符串,每行一个?像这样的东西:

StringBuilder keyRow = new StringBuilder();
StringBuilder value1 = new StringBuilder();
StringBuilder value2 = new StringBuilder();
StringBuilder value3 = new StringBuilder();

Iterator keys = hashmap.keySet().iterator();
boolean notFirst = true;
while(keys.hasNext()) {
    String key = (String)keys.next();
    ArrayList list = (ArrayList)hashmap.get(key);
    if(!notFirst) {
        keyRow.append(",");
        value1.append(",");
        value2.append(",");
        value3.append(",");
    }
    keyRow.append(key);
    value1.append((String)list.get(0));
    value2.append((String)list.get(1));
    value3.append((String)list.get(2));
    notFirst = false;
}

然后在最后,只需拿 4 个字符串

String csv = keyRow.toString()+"\n"+value1.toString()+"\n"+value2.toString()+"\n"+value3.toString();

请注意,此示例不是真正正确的 CSV。带逗号的字符串不包含在引号中。


或者,如果您有数千个这样的行,您将遍历 HashMap 一千次。为了节省查找密钥的时间,您可以将它们全部放在一个ArrayList

StringBuilder csv = new StringBuilder();
int row = 0;
ArrayList<ArrayList> list = new ArrayList<ArrayList>();

// Write the keys row:
Iterator keys = hashmap.keySet().iterator();
boolean notFirst = true;
while(keys.hasNext()) {
    String key = (String)keys.next();
    ArrayList tmp = (ArrayList)hashmap.get(key);
    if(!notFirst) {
        csv.append(",");
    }
    csv.append(key);
    // store list
    list.add(tmp);
    notFirst = false;
}
csv.append("\n");


// Write the rest of the rows
while(row<numberOfTotalRow) {
    notFirst = true;
    for(int x=0;x<list.size();x++) {
        if(!notFirst) {
            csv.append(",");
        }
        csv.append((String)list.get(x).get(row));
        notFirst = false;
    }   
    row++; 
}
于 2012-07-23T04:19:43.447 回答
0

您可以根据需要创建一个打印地图的方法:

public void toString(HashMap<String, ArrayList<String>> map) {
    for(int i = 0; i < map.size(); i++) {
        ArrayList<String> list = new ArrayList<String>(map.keySet());
        String key = list.get(i);
        System.out.println(key);
        for(int j = 0; j < map.get(key).size(); j++)
            System.out.println(map.get(key).get(j));
    }
}
于 2012-07-23T04:18:44.337 回答
0

你想象的方式是不可能的。文件是连续的字节流。因此,在您写入第一个值之后,您的文件中就有:“value1\none\nthree\nfive”。如果您随后寻找位置 6(在“值”之后)并插入新字符,您将覆盖第一个值的第二行。以下字节不会被神奇地推开。

做到这一点的唯一方法是遍历您拥有的数据,使您能够以与它们在文件中相同的顺序输出字节。所以:转到每个值并写入第一个元素,再次到每个值并写入它们的第二个元素,依此类推。

于 2012-07-23T04:21:54.790 回答
0

你不需要RandomAccessFile文件,最好使用这个:

HashMap<String, ArrayList<String>> map = new HashMap<>();
map.put("a", new ArrayList<>(Arrays.asList(new String[]{"A1", "A2", "A3"})));
map.put("b", new ArrayList<>(Arrays.asList(new String[]{"B1", "B2", "B3"})));
map.put("c", new ArrayList<>(Arrays.asList(new String[]{"C1", "C2", "C3"})));
{
    /**
        * Set your file printstream. For testing System.out
        */
    PrintStream ps = System.out;
    boolean first = true;
    /**
        * Size of the array list. Let's asume that the arraylist are of the
        * same lenght;
        */
    int s = 0;
    /**
        * Create a ArrayList variable because, this map class makes no guarantees
        * as to the order of the map; in particular, it does not guarantee that
        * the order will remain constant over time.
        */
    ArrayList<Entry<String, ArrayList<String>>> l =
            new ArrayList<>(map.entrySet());

    for (Entry<String, ArrayList<String>> e : l) {
        if (first) {
            first = false;
            s = e.getValue().size();
        } else {
            ps.print(",");
        }
        ps.print(e.getKey());
    }
    ps.println();

    for (int i = 0; i < s; i++) {
        first = true;
        for (Entry<String, ArrayList<String>> e : l) {
            if (first) {
                first = false;
            } else {
                ps.print(",");
            }
            ps.print(
                    e.getValue().get(i));
        }
        ps.println();
    }
}

输出:

b,c,a
B1,C1,A1
B2,C2,A2
B3,C3,A3
于 2012-07-23T06:06:10.680 回答