当键已存在于地图中时将值推送到地图

Push values to a map when key is already exisitng in a map

我已经声明了一张地图如下:

 Map<String, String[]> test = new HashMap<String, String[]>();

我有一个变量 empnames,它是一个数组,deptname 是一个字符串,我已将 deptname 和 empnames 声明如下:

 String deptname = ['Department']
 String empnames = [['Test1']['Test2']]

 if (deptname != null)
        {
            if (test.containsKey(deptname))
                {
                    ///
                }
                else
                {

                    test.put(deptname, new String[]{empnames}); 
                }
            }

如果测试映射已经包含 deptname 键,那么我应该在什么条件下写入 if 条件以将新值附加到部门?

ArrayList<String> departmentList;
    if(test.containsKey(key)){
        // if the key has already been used, then and add a new value to it
        list = test.get(key);
        list.add(value);
        test.put(key, list);
    } else {
        // if the key hasn't been used yet, then create a new ArrayList<String> object, add the value
        list = new ArrayList<String>();
        list.add(value);
        test.put(key, list);
    }

您可以使用 Java 8 中的新方法,例如 putIfAbsent to add new entry if key is not present and computeIfPresent 将值附加到映射的现有键。

例如:

public static void main(String[] args) {
  Map<String, String[]> test = new HashMap<>();
  String deptname = "Department";
  String[] empnames = {"Test1", "Test2"};

  if (deptname != null){
       test.putIfAbsent(deptname, empnames);
       test.computeIfPresent(deptname, (dept, value) -> {
            List<String> list = new ArrayList<>(Arrays.asList(value));
            list.add("Test3");
            value = list.toArray(value);
            return value;
       });
  }

  for(String s : test.get("Department")){
     System.out.println(s);
  }
}

此处 putIfAbsent 测试键是否存在,如果不存在则添加新的键值条目。另一方面,computeIfAbsent 测试键是否存在,如果存在,它会计算现有键值条目的新值。

以上代码的输出为:

Test1
Test2
Test3 

这是因为最初键 Department 不存在于映射 test 中,因此它与值 empnames 一起作为数组添加到其中。

在第二个操作中,方法 computeIfPresent 检查键 Department 已经在映射中,因此它将新字符串 Test3 附加到 [=23= 的现有值数组中].

可以对 List 而不是数组执行相同的操作:

public static void main(String[] args) {
       Map<String, List<String>> test = new HashMap<>();
       String deptname = "Department";
       List<String> empnames = new ArrayList(Arrays.asList("Test1", "Test2"));

       if (deptname != null){
           test.putIfAbsent(deptname, empnames);
           test.computeIfPresent(deptname, (dept, value) -> {
               value.add("Test3");
               return value;
           });
       }

       for(String s : test.get("Department")){
           System.out.println(s);
       }
 }

正如其他人所建议的,如果您使用 ArrayList 而不是 String[],这会更容易。 但是因为你有一个 String[],你将不得不创建一个 old_array's_size + list_to_add 的新数组,并将旧数组中的值复制到新数组加上您要追加的新值。

所以在你的 if 语句中:

String [] oldList = test.get(deptName);
String[] newList = new String[oldList.length + empnames.length]; //Make a new array with enough space for the previous values at deptname but also the new ones you want to add

//Put all of the values from the existing value at deptname into a new array
for (int i = 0; i < oldList.length; i++)
newList[i] = oldList[i];

//Put all of the values from the list of values you want to add into the new array
for (int i = 0; i < empnames.length; i++)
newList[oldList.length + i] = empnames[i];

test.put(deptname, newList); //Put the completed list back into the map

同样,如果您使用某种列表,这会更容易。除了能够追加之外,一个很好的理由是您可以使用 Collections.sort.

轻松地按字母顺序对其进行排序

由于您标记了 [grails],我认为 Groovy 答案也是合适的。您可以使用带有 .withDefault{ ... } 的地图来提供内容,以防密钥丢失。例如

def data = [["x", ["a", "b"]], ["x", ["c", "d"]]]

def test = [:].withDefault{[]} // XXX

data.each{ k, vs ->
    test[k].addAll(vs) // if there is no key `k`, create an empty array, so `.addAll` just works
}

println(test.inspect())
// => ['x':['a', 'b', 'c', 'd']]