简体   繁体   English

从地图交换密钥 <Key, List<Values> &gt;

[英]Swapping key from a Map<Key, List<Values>>

I'm searching a solution for this problem(it is for an exam): 我正在寻找此问题的解决方案(用于考试):

I have a Map < String, SortedSet < String > > operators populated by a function 我有一个由函数填充的Map <String,SortedSet <String>> 运算符

public void addOperator(String operatorName, String... destinationNames) throws ProposalException {
    if(operators.containsKey((operatorName))){
        throw new ProposalException("Operator " + operatorName + "already into system!");
    }
    else{
        SortedSet<String> destinationstemp=new TreeSet<>();
        for(String s: destinationNames){
            if(s!=null){
                destinationstemp.add(s);
            }
        }
        operators.put(operatorName, destinationstemp);


    }

Now, i want to create a new Map < String, SortedSet < String > > destinations that has as key the destinationName and as values the operatorNames related. 现在,我想创建一个新的Map <String,SortedSet <String>> 目标 ,该目标具有destinationName作为关键字和与operatorNames相关的值。

How can i make this out? 我怎样才能做到这一点?

PS: this one up there is the usage of the methods and the not-in-code part is the output wanted. PS:这是方法的用法,非代码部分是所需的输出。 Sorry for the bad formattation of the code. 对不起,代码格式错误。 ph is the instance of the façade pattern class ph是外观模式类的实例

    public SortedSet<String> getDestOperators(String destinationName) {...}//method that returns the **destinations** values related to destinationName}
ph.addOperator("op3","london","rome");
 ph.addOperator("op2","london","berlin");
 ph.addOperator("op5","berlin","rome","madrid");
ph.addOperator("op1","london","madrid","berlin");
 ph.addOperator("op10","rome");
 ph.addOperator("op4","madrid","berlin"); 
 System.out.println(ph.getDestOperators("madrid"));

Output: [op1, op4, op5] 输出:[op1,op4,op5]

you need to go through each entry in your map and check if inner set contains the value you are checking against, 您需要遍历地图中的每个条目,并检查内部集合是否包含您要检查的值,

public SortedSet<String> getDestOperators(String destinationName) {
   Set<String> result = new HashSet<String>();
   for(Map.Entry<String,Set<String>> entry : operators.getValues()){

      if(entry.getValue().contains(destinationName)){
          results.add(entry.getKey());
      }
   }

  return result;
}

To get your example output a simple one-liner with streams: 为了使示例输出一个简单的带有流的单线:

List<String> result = operators.entrySet().stream().filter(entry -> entry.getValue().contains(destinationName)).map(Entry::getKey).sorted().collect(Collectors.toList());

or here for better readability spread over multiple lines: 或为了提高可读性而在此处分散在多行上:

List<String> result = operators
      .entrySet()
      .stream()
      .filter(entry -> entry.getValue().contains(destinationName))
      .map(Entry::getKey)
      .sorted()
      .collect(Collectors.toList());

A more complex one-liner if you want to "reverse" the mapping as described in your text: 如果要按文本中的描述“反转”映射,则使用更复杂的单行代码:

Map<String, List<String>> result = operators.entrySet().stream().flatMap(entry -> entry.getValue().stream().collect(Collectors.toMap(Function.identity(), o -> Arrays.asList(entry.getKey()))).entrySet().stream()).collect(Collectors.toMap(Entry::getKey, Entry::getValue, (a, b) -> Stream.of(a, b).flatMap(List::stream).sorted().collect(Collectors.toList())));

or here for better readability spread over multiple lines: 或为了提高可读性而在此处分散在多行上:

Map<String, List<String>> result2 = operators
      .entrySet()
      .stream()
      .flatMap(entry -> entry
            .getValue()
            .stream()
            .collect(Collectors.toMap(Function.identity(),
                                      o -> Arrays.asList(entry.getKey())))
            .entrySet()
            .stream())
      .collect(Collectors.toMap(Entry::getKey,
                                Entry::getValue,
                                (a, b) -> Stream.of(a, b)
                                      .flatMap(List::stream)
                                      .sorted()
                                      .collect(Collectors.toList())));

What you need to do, is loop over each operator, and then loop over all entries in the list, if value from the list is not yet present in your output map, you add it, else you modify its colection of operators. 您需要做的是,遍历每个运算符,然后遍历列表中的所有条目,如果输出映射中还没有列表中的值,则添加它,否则修改其运算符集合。 Here is some code for you: 这是一些适合您的代码:

origin.forEach((key, list) -> {list.forEach(city -> {
            if(result.containsKey(city))
                result.get(city).add(key);
            else{
                SortedSet<String> set = new TreeSet<>();
                set.add(key);
                result.put(city, set);
                });
        });

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM