【问题标题】:Searching a Hashmap for values of type list, retrieving an element of list and adding it to a new Collection to return在 Hashmap 中搜索列表类型的值,检索列表元素并将其添加到新集合以返回
【发布时间】:2017-04-28 16:03:07
【问题描述】:

我对 Java 还很陌生,但我希望能解决这个问题。

我目前有一个班级,在那个班级中我有一个名为“departments”的 TreeMap,它的参数为 >:

TreeMap <String, List<String>> department;

在 HR、Builders 等每个部门中,都有一份在那里工作的人员名单。如:

HR:珍妮特、琼斯、鲍勃

我想做的是在部门中搜索以查找所有包含例如称为“鲍勃”的人的部门(键),并将它们添加到集合中以进行返回。

谁能帮忙解决这个问题,我已经把头发拔了好几天了!到目前为止,我的方法已经到此为止了,尽管显然还远未完成!

public List<String> selectValues( String... aValue)

{

for(String eachDept : department.keySet()){
  Collection<String> peopleInTheDept = department.get(eachDept);
  for(String person : aValue){
      if(peopleInTheDept.contains(person)){
          result.add(person);
      }
  }
}
System.out.println(result);
}

【问题讨论】:

  • 您的akey 我想是要搜索的人员列表吧?
  • 没错,抱歉刚刚编辑和更新以反映 aValue
  • 为什么要将数组传递给get 方法?不应该是String作为关键吗?然后containsValue 的值同样是department 的值List&lt;String&gt; 不是数组。另一个问题是,您没有存储从 get 方法检索到的值或对其进行任何操作。
  • 很快有人可能会发布一些花哨的 java 8 流解决方案,但手动的 pre java 8 解决方案将遍历您的 entrySet (department.entrySet())。
  • IMO 将地图设为 TreeMap&lt;String, HashSet&lt;String&gt;&gt; 并遍历每个部门并搜索列表中的每个值 aValue 更有意义

标签: java hashmap treemap


【解决方案1】:

正如 OH GOD SPIDERS 预测的那样,有一个 Java 8 流解决方案:

TreeMap <String, List<String>> department = new TreeMap<>();
department.put("AB", Arrays.asList("Bob", "Truus", "Miep"));
department.put("CD", Arrays.asList("Jan", "Kees", "Huub"));
department.put("EF", Arrays.asList("Jan", "Piet", "Bert"));
String aValue = "Jan";

Map<String,List<String>> result = department.entrySet().stream()
// filter out those departments that don't contain aValue
  .filter(entry -> entry.getValue().contains(aValue))
// collect the matching departments back into a map 
  .collect(Collectors.toMap(k -> k.getKey(), k -> k.getValue()));

// print the result
result.forEach((k,v)-> System.out.println(k + " " + v.toString()));

哪些打印:

EF [Jan, Piet, Bert]
CD [Jan, Kees, Huub]

Pre Java 8 解决方案:

Map<String, List<String>> result2 = new TreeMap<>();

for(String eachDept : department.keySet()){
    List<String> peopleInTheDept = department.get(eachDept);
    if(peopleInTheDept.contains(aValue)){
            result2.put(eachDept, department.get(eachDept));
    }
}
for (String s : result2.keySet()){
    System.out.println(s + " " + result2.get(s));
}

这与我的 Java 8 代码完全相同。

【讨论】:

  • 有非 Java 8 的答案吗?
  • 它是但它不编译:/
  • @JamesPalfrey 已为我的答案添加了 pre java 8 解决方案
  • 它可以编译但我没有打印出来?
  • @JamesPalfrey 最后三行为我打印了结果。这与 Java 8 无关
【解决方案2】:

这里有一些java 8 Streams 奇特的解决方案,用于获取信息并填写您的列表。

public void selectValues(String... values)
{
   for(String value : values) {
     results.addAll(department.entrySet()
         .stream()
         .filter(entry -> entry.getValue().contains(value))
         .map(entry -> entry.getKey())
         .collect(Collectors.toList()));
   }
}

【讨论】:

  • 我知道它应该大致看起来像这样,但不太确定如何填充它: public List findCustomersInArea(int x) { // 创建一个列表来存储所有客户 List x = x(); // 迭代地图中的所有条目 for (x.x x: x.x()) { // 获取客户 x x = x.x(); if (x.x() == x) { // 做你需要添加到列表中的事情 x.x(x); } } // 返回所有 x 的列表 return x;
【解决方案3】:

据我了解,您需要一个 department 列表,其值包含特定名称。这是Java 8版本的解决方案。

public static void main(String[] args) {
    // Initialization of map
    Map<String, List<String>> department = new TreeMap<>();
    department.put("HR", new ArrayList<>());
    department.put("ACC", new ArrayList<>());
    department.put("MK", new ArrayList<>());

    department.get("HR").add("bob");
    department.get("HR").add("John");

    department.get("ACC").add("Kim");
    department.get("ACC").add("bob");

    department.get("MK").add("XXX");

    // Here is the solution
    // depts is a list of string which contains the name of
    // department who's value contains 'bob'
    List<String > depts = department.entrySet()
            .stream()
            .filter(i -> i.getValue().contains("bob"))
            .map(Map.Entry::getKey)
            .collect(Collectors.toList());

    // Printing out the result
    depts.stream().forEach(System.out::println);
}

传统方式

    List<String> depts = new ArrayList<>();
    for (Map.Entry<String , List<String >> it : 
            department.entrySet()) {
        if (it.getValue().contains("bob"))
            depts.add(it.getKey());
    }

【讨论】:

    【解决方案4】:

    Java8 的流肯定是一个优雅的解决方案……但是如果您限制使用 java 8,那么您的部门如何使用TreeMap&lt;String, Set&lt;String&gt;&gt; 类型。如果您坚持使用列表,则非常相似。只需将设置更改为列表。 List接口中也有contains方法。

    TreeMap<String, List<String>> departments = new TreeMap<String, List<String>>();
    ArrayList<String> myList = new ArrayList<String>();
    myList.add("person1");
    departments.put("dep1", myList);
    String[] aValue = {"person1","person2"};
    
    public void selectValues( String... aValue)
    
    {
    
      for(String eachDept : departments.keySet()){
          List<String> peopleInTheDept = departments.get(eachDept);
          for(String person : aValue){
              if(peopleInTheDept.contains(person)){
                  result.add(person)
              }
          }
      }
      System.out.println(result);
    }
    

    可能有类似的东西?

    【讨论】:

    • 您的部门是 `TreeMap> 部门 = new TreeMap>();' ?
    • 它是 TreeMap> 部门的类型;
    • 编辑了我的答案,为您提供更多说明。
    • 感谢向导,我无法将 TreeMap 更改为采用 Set 集合而不是 List 集合,因为它会抛弃其他方法……是否有使用列表的方法?跨度>
    • 当然我建议 Set 只是为了让您的搜索高效...更新了答案以使用列表。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多