用Java

时间:2016-01-26 02:31:34

标签: java dictionary initialization

我很好奇如何在Java中更有效地实例化字典。目前我有可通过的代码,但我以非常模糊的方式填充数据。

有没有办法让我初始化我的字典?这是记录的python:

westernCanadaAdjList =  {  'BC': ['AB'],
                       'AB': ['BC', 'SK'],
                       'SK': ['AB', 'MB'],
                       'MB': ['SK']
                        }

我发现用于演示的目的更加清晰。

我目前在Java中的代码:

public class Main {

public static void main(String[] args) {

    //Adjacency List representation through a dictionary. Allows fast O(1) lookup time.
    Map<String,ArrayList<String>> adjList = new HashMap<String,ArrayList<String>>();


    //Adding values for Edmonton
    adjList.put("Edmonton", new ArrayList<String>());
    adjList.get("Edmonton").add("Neighbour1");
    adjList.get("Edmonton").add("Neighbour2");
    adjList.get("Edmonton").add("Neighbour3");


    //Adding values for Vancouver
    adjList.put("Vancouver", new ArrayList<String>());
    adjList.get("Vancouver").add("V neighbour1");
    adjList.get("Vancouver").add("V neighbour2");

    System.out.println(adjList.keySet() +" And Values " +  adjList.values());

    for (String neighbour: adjList.get("Edmonton")){
        System.out.println(neighbour);
    }

    for (String neighbour: adjList.get("Vancouver")){
        System.out.println(neighbour);
    }
  }
}

非常感谢!

4 个答案:

答案 0 :(得分:6)

这是我所知道的最好的技术:

    Map<String, String> myMap = new HashMap<String, String>() {{
        put("foo", "bar");
        put("key", "value");
        //etc
    }};

请注意双括号 - 这通常称为双括号初始化。

你真正在做的是创建一个扩展HashMap的匿名内部类,你的新子类包含一个初始化块,你可以在其中调用任何保证在使用实例之前执行的任意代码。 / p>

另请注意,无论出于何种原因,'diamond operator'都不能与匿名类一起使用。

对于测试类来说,这是一种很好的技术,但我倾向于将其用于生产代码。

编辑:我想我应该回答你的实际问题!

双支撑初始化可能是“纯”Java中的最佳解决方案,您的Map将具体看起来像:

    Map<String, List<String>> westernCanadaAdjList = new HashMap<String, List<String>> () {{
        put("BC", new ArrayList<String>(){{ add("AB"); }});
        put("AB", new ArrayList<String>(){{ add("BC"); add("SK"); }});
        put("SK", new ArrayList<String>(){{ add("AB"); add("MB"); }});
        put("MB", new ArrayList<String>(){{ add("SK"); }});
    }};

......仍然不是超级棒。 Java确实需要一个Map文字,而且它没有。

对于生产代码,我会使用Guava的MultiMap,但老实说用文字填充它并不是更好:

    Multimap<String, String> multimap = ArrayListMultimap.create();
    multimap.put("BC", "AB");
    multimap.put("AB", "BC");
    multimap.put("AB", "SK");
    multimap.put("SK", "SK");
    multimap.put("SK", "SK");
    multimap.put("SK", "SK");

答案 1 :(得分:2)

是的,您可以:将其解析为json:

import com.fasterxml.jackson.databind.ObjectMapper;

String json = "{'BC': ['AB']," +
              "'AB': ['BC', 'SK']," +
              "'SK': ['AB', 'MB']," +
              "'MB': ['SK']"
              "}";

Map<String, Object> map = new ObjectMapper().readValue(json, HashMap.class);

答案 2 :(得分:1)

我同意路易斯并且不打算添加任何东西。

在这种情况下使用流可以让你将代码压缩成一行,但我意识到这不是你问题的答案(只是我能想到的最接近)。

        Map<String, List<String>> adjList = Stream.of(
            new SimpleEntry<>("Edmonton", Arrays.asList("E N1", "E N2", "E N3")), 
            new SimpleEntry<>("Vancouver", Arrays.asList("V N1", "V N2", "V N3")))
            .collect(Collectors.toMap((e) -> e.getKey(), (e) -> e.getValue()));

答案 3 :(得分:1)

我最近遇到了类似的问题。我将数据表示为2d数组,相对容易键入和解析,并编写了一个实用程序方法来将其解析为数据结构。例如为你的情况

static String[][] CANADA_DATA = {
  {"BC"," AB"},
  {"AB","BC","SK"},
  // rest of Canada here
}

示例代码

public Map<String, List<String>> parseIt() {

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

   for (String[] provinceData : CANADA_DATA ) {
      String name = provinceData [0];
      ArrayList neighbors = new ArrayList(Arrays.asList(provinceData ));
      neighbors.remove(0);  // remove ourself
      map.put(name, neighbors);
   } 

   return map; 
}

显然,您可以更改数据格式并解析代码以满足您的特定需求。