简体   繁体   English

将哈希图中的数据作为CSV文件写入

[英]write data from hashmap as a CSV file

Say I have a hashmap with String type as key and ArrayList type as value, example {"value1"=["one","three","five"], "value2"=["two","four","six"]} where "value1" and "value2" are keys. 假设我有一个哈希图,其中String类型为键,而ArrayList类型为值,例如{"value1"=["one","three","five"], "value2"=["two","four","six"]} ,其中“ value1”和“ value2”是键。 I want to write the above hashmap data in following format. 我想以以下格式编写上面的哈希图数据。 (so that I can read the csv file in excel) (以便我可以在excel中读取csv文件)

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

My idea was to write the first key and its values as follows 我的想法是编写第一个键及其值,如下所示

value1
one
three
five

Then I was thinking of using the seek method in RandomAccessFile class to back to line 1 and again write the second key and its values. 然后我在考虑使用RandomAccessFile类中的seek方法返回到第1行,并再次写入第二个键及其值。 However I am not able to accomplish this task since seek function takes in the length of strings in the entire file and writes the new string after it. 但是,我无法完成此任务,因为seek函数会吸收整个文件中字符串的长度,然后在其后写入新字符串。 While I wanted the pointer to jump to the first line and append the string. 当我希望指针跳到第一行并追加字符串时。 Is there a better way to do this?. 有一个更好的方法吗?。 A quick example would be much appreciated. 一个快速的例子将不胜感激。

Thanks 谢谢

Why can't you just use 4 Strings, one for each row? 为什么不能只使用4个字符串,每行一个? Something like this: 像这样:

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;
}

Then at the end, just take the 4 Strings 然后最后,取4个琴弦

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

Note that this example isn't really proper CSV. 请注意,此示例并不是真正正确的CSV。 Strings with commas aren't wrapped in quotes. 带逗号的字符串不用引号引起来。


Or you iterate through the HashMap a thousand times if you have thousands of these rows. 或者,如果您有成千上万的此类行,则对HashMap进行1000次迭代。 To save a bit of time from looking up a key, you can put them all in an ArrayList : 为了节省查找键的时间,您可以将它们全部放入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++; 
}

You can make a method that prints out the map as you wish: 您可以根据需要创建一种打印地图的方法:

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));
    }
}

The way you have imagined is impossible. 您想象的方式是不可能的。 A file is a continuous stream of bytes. 文件是连续的字节流。 So after you write the first value, you have this in your file : "value1\\none\\nthree\\nfive". 因此,在写入第一个值之后,文件中将包含此值:“ value1 \\ none \\ nthree \\ nfive”。 If you then seek to position 6 (after "value") and insert new characters, you'll be overwiting the first value's second row. 然后,如果您试图将位置6(在“值”之后)并插入新字符,则将忽略第一个值的第二行。 The following bytes won't be magically pushed away. 接下来的字节不会被神奇地推开。

The only way to do this is to traverse the data you have in a way that allows you to output the bytes in the same order that they will be in the file. 唯一的方法是遍历您拥有的数据,使您可以按照与文件中相同的顺序输出字节。 So: go to each value and write the first element, to each value again and write their second element and so on. 因此:转到每个值并写入第一个元素,再次写入每个值并写入其第二个元素,依此类推。

You don't need a RandomAccessFile file, better use this: 您不需要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();
    }
}

Output: 输出:

b,c,a
B1,C1,A1
B2,C2,A2
B3,C3,A3

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM