存储以长度为键的字符串的关联数组

时间:2013-01-04 18:27:58

标签: java string collections associative-array

我有这个输入:

5
it
your
reality
real
our

第一行是后来的字符串数。我应该这样存储它(伪代码):

associative_array = [ 2 => ['it'], 3 => ['our'], 4 => ['real', 'your'], 7 => ['reality']]

正如您所看到的,关联数组的键是存储在内部数组中的字符串的长度。 那么我怎么能在java中这样做呢?我来自php世界,所以如果你将它与php进行比较,那就非常好了。

5 个答案:

答案 0 :(得分:3)

MultiMap<Integer, String> m = new MultiHashMap<Integer, String>();

for(String item : originalCollection) {
    m.put(item.length(), item);
}

答案 1 :(得分:1)

djechlin已经发布了一个更好的版本,但这里只是使用JDK类的完整独立示例:

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;    
   public class Main {
        public static void main(String[] args) throws Exception{
            BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
            String firstLine = reader.readLine();
            int numOfRowsToFollow = Integer.parseInt(firstLine);
            Map<Integer,Set<String>> stringsByLength = new HashMap<>(numOfRowsToFollow); //worst-case size
            for (int i=0; i<numOfRowsToFollow; i++) {
                String line = reader.readLine();
                int length = line.length();
                Set<String> alreadyUnderThatLength = stringsByLength.get(length); //int boxed to Integer
                if (alreadyUnderThatLength==null) {
                    alreadyUnderThatLength = new HashSet<>();
                    stringsByLength.put(length, alreadyUnderThatLength);
                }
                alreadyUnderThatLength.add(line);
            }
            System.out.println("results: "+stringsByLength);
        }
    }

它的输出如下:

3
bob
bart
brett
results: {4=[bart], 5=[brett], 3=[bob]}

答案 2 :(得分:1)

Java没有关联数组。但它确实有Hashmaps,它主要实现了同样的目标。在您的情况下,您可以为任何给定的键具有多个值。所以你可以做的是让Hashmap中的每个条目成为一个数组或某种集合。 ArrayList是一个可能的选择。那就是:

Hashmap<Integer,ArrayList<String>> words=new HashMap<Integer,ArrayList<String>>();

我不打算通过代码从文件或其他内容中读取列表,这是一个不同的问题。但只是为了让您了解结构如何工作,假设我们可以对列表进行硬编码。我们可以这样做:

ArrayList<String> set=new ArrayList<String)();
set.add("it");
words.put(Integer.valueOf(2), set);
set.clear();
set.add("your");
set.add("real");
words.put(Integer.valueOf(4), set);

In practice, you probably would regularly be adding words to an existing set. I often do that like this:

void addWord(String word)
{
  Integer key=Integer.valueOf(word.length());
  ArrayList<String> set=words.get(key);
  if (set==null)
  {
    set=new ArrayList<String>();
    words.put(key,set);
  }
  // either way we now have a set
  set.add(word);
}

旁注:我经常看到程序员通过将“set”放回到Hashmap中来结束这样的块,即最后的“words.put(key,set)”。这是不必要的:它已经存在了。当您从Hashmap中获得“设置”时,您将获得一个引用,而不是一个副本,因此您所做的任何更新都只是“存在”,您不必将其放回去。

免责声明:此代码不在我的掌控之中。不作任何明示或暗示的保证。我有一段时间没有写任何Java,所以我可能有语法错误或错误的函数名称。 : - )

答案 3 :(得分:0)

由于您的密钥似乎是小整数,因此您可以使用列表列表。在这种情况下,最简单的解决方案是使用像

这样的MultiMap
Map<Integer, Set<String>> stringByLength = new LinkedHashMap<>();

for(String s: strings) {
   Integer len = s.length();
   Set<String> set = stringByLength.get(s);
   if(set == null)
        stringsByLength.put(len, set = new LinkedHashSet<>());
   set.add(s);
}

答案 4 :(得分:0)

private HashMap<Integer, List<String>> map = new HashMap<Integer, List<String>>();

void addStringToMap(String s) {
    int length = s.length();
    if (map.get(length) == null) {
        map.put(length, new ArrayList<String>());
    }
    map.get(length).add(s);
}