1

文件:

Person1:AP
Person2:AP
Person3:KE
Person4:KE
Person5:UK
Person6:AP
Person7:UK
Person8:AP

我尝试过的是:

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.HashMap;

public class TestNull {

    public static void main ( String args[]) throws IOException {

        BufferedReader br = new BufferedReader ( new FileReader("/home/username/Desktop/test"));
        String str;
        HashMap<String, String> h = new HashMap<String, String>();

        try {
            while ( (str = br.readLine()) != null)  {
                String[] s = str.split(":");
                h.put(s[1],s[0]);
            }
            System.out.println(h);
        }

        catch (FileNotFoundException E) {   
            System.out.println("File Not Found");
        }
        finally {   
            br.close();
        }
    }
}  

我可以通过 Perl 实现这一点:

use strict;
use warnings;

open (FILE,"test");

my %hash=();
while (my $line = <FILE>)   {

    chomp $line;

    my ($name,$country) = split(":", $line);

    chomp ($name,$country);

    $hash{$country} .= "$name ";    
}

for my $keys (keys %hash)   {

    print "$keys: $hash{$keys}\n";

}

从数据文件中,我正在寻找这样的输出:

{AP = [person1, person 2, person6, person8], KE = [person3, person4], UK = [person5, person7]}
4

5 回答 5

2

其他解决方案的替代方案是使用来自 Guava 的 Multimap 实现之一。如果这是您拥有的唯一这样的地图,那么添加这样的依赖项可能有点过头了,但是如果您最终得到一堆这种性质的地图,最好不要到处都有这个样板:

if (!map.containsKey(key)) {
  map.put(key, new List<Foo>());
}
map.get(key).add(value); 

当你可以这样做时:

multimap.put(key, value); 

反而。有许多实现取决于您想要什么。

排序: http: //guava-libraries.googlecode.com/svn/tags/release03/javadoc/com/google/common/collect/TreeMultimap.html

与您添加它们的顺序相同:http: //guava-libraries.googlecode.com/svn/tags/release03/javadoc/com/google/common/collect/LinkedHashMultimap.html

不关心订购: http: //guava-libraries.googlecode.com/svn/tags/release03/javadoc/com/google/common/collect/HashMultimap.html

https://code.google.com/p/guava-libraries/

于 2013-06-04T04:40:17.890 回答
2

以下是您需要的 -

Map<String, List<String>> h = new HashMap<String, List<String>>();

对于每一行 -

String[] s = str.split(":"); //s[1] should be the key, s[0] is what should go into the list 
List<String> l = h.get(s[1]); //see if you already have a list for current key
if(l == null) { //if not create one and put it in the map
    l = new ArrayList<String>();
    h.put(s[1], l);
}
l.add(s[0]); //add s[0] into the list for current key 
于 2013-06-03T23:49:30.250 回答
2

要将地图颠倒过来,您可能需要这样:

HashMap<String, String> h = new HashMap<String, String>();
...
// your reading code
...
HashMap<String,ArrayList<String>> map = new HashMap<String,ArrayList<String>>();
...
for(String key: h.keySet()) {
    if(!map.hasKey(key)) {
        map.put(key, new ArrayList<String>());
    }
    map.get(key).add(h.get(key));
}

现在“map”包含所需的结构化数据,“AP”指向一个数组列表(person1、person 2、person6、person8)等。

于 2013-06-03T23:53:41.537 回答
0

HashMap.put()将替换您已插入哈希映射的任何元素。您需要首先尝试检索地图中的现有键,如果它已经存在(即,为前一个输入行插入),那么您可以将当前名称附加到其值,然后将其重新插入到地图中.

此外,您可能会想要使用类似List<String>的东西来保存地图值(名称),而不仅仅是一个String. 使用列表还可以节省您重新插入值的需要,因为您可以只附加到地图中已经存在的列表中。

于 2013-06-03T23:50:21.033 回答
0

您只需要更改while地图的和类型:

Map<String, List<String>> h = new HashMap<String, List<String>>();

/* (...) */

while ( (str = br.readLine()) != null)  {

    String[] s = str.split(":");
    list = h.get(s[1]);
    if(list==null) {
        list = new ArrayList<String>();
    }
    list.add(s[0]);
    h.put(s[1],list);

}
于 2013-06-03T23:51:27.023 回答