HashMap问题的多个唯一键(Java)

时间:2010-04-24 14:58:11

标签: java sorting hashmap

这个问题是this thread

的延续

简而言之:要解决我的问题,我想使用Map<Set<String>, String>

但是,在Excel中对数据条目进行排序后,删除不必要的参数,并出现以下内容:

flow content ==> content content 
flow content ==> content depth distance 
flow content ==> content depth within 
flow content ==> content depth within distance 
flow content ==> content within 
flow content ==> content within distance 

如果是这种情况,我有多个hashmap的唯一键。我如何解决这个问题...任何人都有任何想法?

我想的可能是Map<Set <String>, List <String>>,所以我可以做类似的事情:

Set <flow content>, List <'content content','content depth distance','content depth within ', ..., 'content within distance'>

但是因为我逐行解析条目我无法弄清楚如何将相同重复键(流内容)的值存储到同一列表中并将其添加到地图。

任何人都有关于如何在Java中完成此操作的粗略逻辑?

提前致谢。

- 编辑:

尝试使用Multimap但不知何故有轻微问题:

public static void main(String[] args) {

    File file = new File("apriori.txt");
    Multimap<Set <String>, String> mm = HashMultimap.create();
    Set<String> s = null;
    List l = null;

    BufferedReader br = null;

    try {
            br = new BufferedReader(new FileReader(file));
            String line = "";

            while ((line = br.readLine()) != null) {
                //Regex delete only tokenize

                String[] string = line.split(";");
                System.out.println(string[0] + " " + string[1]);

                StringTokenizer st = new StringTokenizer(string[0].trim());
                while (st.hasMoreTokens()) {
                    //System.out.println(st.nextToken());
                    s = new HashSet<String>();
                    s.add(st.nextToken());
                }
                mm.put(s,string[1]);
            }

        // dispose all the resources after using them.
        br.close();
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }

    Set<String> t = new HashSet<String>();
    t.add("content");
    t.add("by");

    String str = mm.get(t).toString();
    System.out.println(str);

    for (Map.Entry<Set <String>, String> e : mm.entries()) {
        System.out.println(e);
    }
}

apriori.txt

byte_jump ; msg 
byte_jump ; msg by 
content ; msg 
content by ; flow 
content by ; msg 
content by ; msg flow 
content by byte_jump ; msg 
content byte_jump ; by 
content byte_jump ; msg 
content byte_jump ; msg by

显然是forloop的输出:

[content]= msg 
[by]= flow 
[by]= msg 
[by]= msg flow 
[byte_jump]= msg 
[byte_jump]= by 
[byte_jump]= msg by 

而不是[content by] = msg flow

为什么会这样?我试过,它的工作原理。但我需要Set来比较字符串而不管位置。我该怎么办?

4 个答案:

答案 0 :(得分:2)

逻辑基本上是:

  • 按照您的建议映射到列表
  • 将某些内容放入地图中,检索与该键对应的列表
  • 如果列表为null,则创建一个新列表并将该键映射到该新列表
  • 将该项目添加到列表

正如另一张海报所提到的,您可以考虑使用标准的多地图库类,例如Google Collections中提供的类。 (我个人会亲自实现它,因为它非常简单,并且在我看来并不能保证整个额外的库,但里程会有所不同。)

答案 1 :(得分:2)

关于使用MultiMap的代码:您唯一错误的做法是为每个令牌创建一个新集,而不是将一行的所有令牌放入同一个集合中。这也是你丢失令牌的原因。这有效:

s = new HashSet<String>();
while (st.hasMoreTokens()) {
    //System.out.println(st.nextToken());
    s.add(st.nextToken());
}

答案 2 :(得分:1)

multimap允许特定密钥的多个值。

一个实现是作为Multimap的一部分提供的各种Google Collections

不是编码将数据正确存储到Map<String, List<String>的方法,而是继续为工作使用适当的数据结构可能是更好的选择。

答案 3 :(得分:1)

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

    final File file = new File("apriori.txt");
    final Multimap<String, String> map = HashMultimap.create();

    final BufferedReader reader = new BufferedReader(new FileReader(file));

    while (true) {
        final String line = reader.readLine();
        if (line == null) break;
        final String[] parts = line.split(" ; ");
        map.put(parts[0].trim(), parts[1].trim());
    }

    for (Map.Entry<String, String> e : map.entries()) {
        System.out.println(e);
    }
}

应该做的伎俩。 (我没有编译,但没有保证。)
确保使用Multimap<String, String>,不需要在那里使用单个元素集作为键。