2015-10-18 115 views
2

下面是我使用的Map,但是当我运行时,我得到了sonar cycolmatic的复杂性。而不是如果其他如果其他..我想使用Java 8 Stream。如何在Java 8 Streams中编写...请指教。Java 8 Streams for HashMap

Map<String, String> innerMap = new HashMap<String, String>(); 
innerMap.put("ONE" , "ABC"); 
innerMap.put("TWO" , "DEF"); 
innerMap.put("THREE" , "GHI"); 

Map<String, Map<String,String> outerMap = new HashMap<String, Map<String, String>>(); 
outerMap.put("OUTER" , innerMap); 

if(outerMap.containsKey("OUTER")){ 
    if(innerMap.containsKey("ONE")){ 
     call one method..... 
    }else if (innerMap.containsKey("TWO")){ 
     call one method.... 
    }else if(){ 
     ....... 
    } 
} 

谢谢。

+0

“但是当我运行时,我得到了sonar cycolmatic的复杂性”我不知道,你试图告诉我们什么。 – Holger

回答

0

if您的if声明优先级是用于调用方法的关键值,因此除非该优先级顺序已定义良好,否则可能没有更好的方法来执行您正在执行的操作。

这将是不同的,如果你要求每个按键目前的方法,但else子句确保你只要求关键ONE的方法,即使有也是一个关键TWO,并在地图上的一个关键THREE

+0

谢谢安德烈亚斯! – Sudheer

1

使用Java 8,您可以拥有行为参数化。这意味着你可以有一个类(姑且称之为X)与2个属性 - 值(类型= String),方法(Type = Function

所以,你可以构建地图是这样的:

Map<String, X> innerMap = new HashMap<>(); 
innerMap.put("ONE" , new X("ABC", SomeClass::somemethod)); 
innerMap.put("TWO" , new X("DEF", SomeClass::somemethod2)); 
innerMap.put("THREE" , new X("GHI", SomeClass::somemethod3)); 

然后,你可以迭代地图的entrySet(),然后调用function.apply();

+0

谢谢!!在我的情况下,“innerMap”和“outerMap”来自消费者应用程序插入的会话。那么我所了解的是迭代地图,然后像上面说的那样添加一个类? – Sudheer

+0

而不是迭代,如果您对每种类型的键有固定的处理程序方法,则定义处理程序的接口,并创建一个包含每种类型键的特定实现处理程序的枚举。所以,你基本上不必编写if else来确定为每个键类型调用哪个处理程序。 – shiladitya

0

这是一个关于如何通过使用flatMap来嵌套Map的例子。

我会把你的输入StringFunction之间的映射放在一个单独的Map中。

public void withConsumerMap(){ 
    // Create a map of your functions too 
    Map<String, Consumer<String>> functions = new HashMap<>(); 
    functions.put("ONE", this::one); 

    Map<String, String> innerMap = new HashMap<>(); 
    innerMap.put("ONE" , "ABC"); 
    innerMap.put("TWO" , "DEF"); 
    innerMap.put("THREE" , "GHI"); 

    Map<String, Map<String,String>> outerMap = new HashMap<>(); 
    outerMap.put("OUTER" , innerMap); 

    outerMap.entrySet().stream() 
      .filter(outer -> outer.getKey().equals("OUTER")) 
      .flatMap(outer -> outer.getValue().entrySet().stream()) 
      .forEach(inner -> functions.get(inner.getKey()).accept(inner.getValue())); 
} 

public void one(String param){ ... } 

在上面的例子中,我使用java.util.function.Consumer,它们取一个输入,并返回void。如果你需要你的函数来返回一些东西。改为使用java.util.function.Function

+0

在整个地图上迭代并通过将键与常量进行过滤来过滤“Map”概念。 “Map”提供像get或者containsKey这样的方法是有原因的。这是因为这些操作可以使用实际地图实现工作的方式高效地实现。根据实现的不同,它们的时间复杂度为'O(1)'或'O(log(n))',而你忽略它们并使用'O(n)'操作。 – Holger

+0

@霍尔我以为你错过了这一点。我的示例代码显示了如何使用流来遍历'Maps'的示例。它没有显示解决这类问题的最佳代码。但那不是问题。 – tomaj

+0

SO的主要目标是*解决问题*不要表明如何处理任意的前提,忽略强烈的理由,永远不要这样做。最起码要做的是提出原因,不要这样做,正确的答案。但更好的答案是“不要与流,它不解决你的问题”。 – Holger

0

为什么不这样做?为什么你需要这样的流?

Map<String, Runnable> executionPath = new HashMap<>(); 
    executionPath.put("OUTER-ONE", runnable1); 
    executionPath.put("OUTER-TWO", runnable2); 

    // I guess you want to pass the arg - such as "OUTER-ONE" 

    executor.execute(executionPath.get(arg));