2009-12-28 24 views
1

我坚持在这里:使用Hashmap来处理多个键值,为什么?

我输入文件:

123 456 789 
872 727 282 
123 838 831 
818 833 939 

现在,我需要保存在一个HashMap二维数组数据,或任何最好的可能的替代是这样的:

key value 
123 -> 456, 789, 838, 831 
872 -> 727, 282 
818 -> 833, 939 

什么是最好的方式(简单和优化)来实现这一点,并使用什么?

我在尝试Map<String, List> rawData = new HashMap<String, List>();但没有成功。

我是新来的java。 :)

+0

“精简优化” - 尼斯的要求。可能是得可徘徊。 – 2009-12-28 13:47:10

+0

所有键/值总是数字吗?如果是这样,0123与0123不同?另外,如果他们都是数字,他们可以多大/多小? – MAK 2009-12-28 14:31:25

+0

是否需要合并右侧三元组中的任何副本?该列表是否真的是有序集合,还是它必须容忍重复? – seh 2009-12-28 14:36:02

回答

11
​​

我不太确定java方法的确切名称,但这应该主要是它。每个HashMap键指向一个包含您的选项的LinkedList

+5

我会考虑使用集而不是列表,以防我不希望重复收集价值集合 – Yaneeve 2009-12-28 14:08:37

+0

是的,保留重复是我的req中不可接受的。那么,设置将是一个更好的选择? – zengr 2009-12-28 14:12:01

+1

@unknown,是一个集将删除所有重复你。 LinkedHashSet将保留插入顺序,但如果您不关心顺序,请使用HashSet。如果你想排序,使用TreeSet。 – Yishai 2009-12-28 14:30:36

0

我们你的语法和ruibm的语法,以防万一结合你要换个角度:

String key = "123"; 
String value = "456"; 
Map<String, ArrayList> rawData = new HashMap<String, ArrayList>(); 
if(!rawData.containsKey(key)){ 
    rawData.put(key, new ArrayList()); 
} 
rawData.get(key).add(value); 
+0

进行格式化...但Jung对原始答案进行了一些编辑,类似于我的答案。 – user239585 2009-12-28 14:32:03

+0

好的,对我来说工作正常,只是最后一个问题,当我编译java文件时,它给出了一个警告: 注意:filenae。java使用未经检查或不安全的操作。 注意:使用-Xlint重新编译:取消选中以获取详细信息。因为这一行: Data.put(key,new ArrayList()); 这是一个严重的问题吗? – zengr 2009-12-28 16:16:54

+0

您的警告是因为您在实例化ArrayList时没有使用泛型。 – Eldelshell 2009-12-28 16:47:51

0

这是一个相当严格的版本,规定如下:

  • 每个键和每个值是数字三位数
  • 每行必须定义一个键和至少一个数值
  • 为同一个键重复的值不合并到数值l中IST
  • 的空间的任何量的每个三元组

后耐受Matcher的重复分配可以被优化,以使用Matcher#reset()代替,但在一些清晰度损失。

private static <T extends Appendable> T collectLineInto(Reader source, T sink) 
    throws IOException 
{ 
    for (int read = source.read(); 
     -1 != read && '\n' != read; 
     read = source.read()) 
    { 
    sink.append((char)read); 
    } 
    return sink; 
} 


static Map<Integer, List<Integer>> read(Reader reader) 
    throws IOException 
{ 
    final Pattern head = Pattern.compile("(\\d{3}) +(\\d{3})(?: +|$)"); 
    final Pattern tail = Pattern.compile("\\G(\\d{3})(?: +|$)"); 
    final Map<Integer, List<Integer>> result = 
    new HashMap<Integer, List<Integer>>(); 
    for (final StringBuilder buf = new StringBuilder(11); 
     0 != collectLineInto(reader, buf).length(); 
     buf.setLength(0)) 
    { 
    final Matcher m = head.matcher(buf); 
    if (!m.lookingAt()) 
     throw new IOException("Encountered invalid entry"); 

    final Integer key = new Integer(m.group(1)); 
    List<Integer> values = result.get(key); 
    if (null == values) 
    { 
     values = new LinkedList<Integer>(); 
     result.put(key, values); 
    } 
    values.add(Integer.parseInt(m.group(2))); 
    m.usePattern(tail); 
    while (!m.hitEnd()) 
    { 
     if (m.find()) 
     values.add(Integer.parseInt(m.group(1))); 
     else 
     throw new IOException("Encountered invalid triple"); 
    } 
    } 
    return result; 
} 


static Map<Integer, List<Integer>> read(InputStream is, Charset cs) 
    throws IOException 
{ 
    return read(new InputStreamReader(is, cs)); 
} 
+0

@seh老兄,你摇滚! – zengr 2009-12-28 16:29:00

+0

谢谢。我更新了'read()'函数来检测并报告无效的输入数据。 – seh 2009-12-29 16:14:28

相关问题