2015-10-18 5 views
2

Ниже приведена карта, которую я использую, но когда я бегу, я получаю сложность сонара. вместо этого, если else if else .. Я хотел бы использовать Java 8 Stream. Как написать это в Java 8 Streams ... Пожалуйста, совет.Java 8 Streams для 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

«но когда я бегу, я получаю сонарную циклическую сложность». Я понятия не имею, что вы пытаетесь нам рассказать. – Holger

ответ

0

Операторы if присваивают приоритеты ключевому значению, которое будет использоваться для вызова метода, поэтому, если этот приоритетный порядок не определен, вероятно, нет лучшего способа делать то, что вы делаете.

Было бы иначе, если бы вы вызываете метод для каждого ключа настоящее, но положение else гарантирует, что вы только вызов метода для ключа ONE, несмотря на то, что есть также ключ TWO и ключ THREE на карте ,

+0

Спасибо, Андреас !! – Sudheer

1

С Java 8 вы можете иметь параметризацию поведения. Это означает, что вы можете иметь класс (назовем его X) с 2-мя атрибутами - значение (тип = String), метод (тип = 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

вместо итерации, если у вас есть фиксированные методы обработчика для каждого типа ключа, определить интерфейс обработчика и создать перечисление, которое содержит конкретные обработчики реализации для каждого типа ключа. Поэтому вам по существу не нужно писать, если иначе определить, какой обработчик вызывает для каждого типа ключа. – shiladitya

0

Вот пример того, как поток через вложенный Map использует flatMap.

Я бы поставил сопоставления между вашим вводом String и Function на отдельной карте.

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

Итерация по всей карте и фильтрация путем сравнения ключа с константой искажают концепцию «Карта». Существует причина, почему «Карта» предоставляет такие методы, как 'get' или' containsKey'. Это связано с тем, что эти операции могут быть эффективно реализованы с использованием того, как работает фактическая реализация карты. В зависимости от реализации они имеют временную сложность «O (1)» или «O (log (n))», и вы игнорируете их и вместо этого используете операцию «O (n)». – Holger

+0

@ Хольгер Я думаю, что вам не хватает смысла. В моем примере кода показан пример того, как вы можете использовать потоки для итерации над «Картами». Он не показывает оптимальный код для решения этой проблемы. Но это был не вопрос. – 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)); 
Смежные вопросы