2016-11-20 14 views
3

在C++中,我會用地圖INT /指針像這樣的功能:如何避免在java中執行大量if?

std::map = { 
{Code::Value1, Handler::value1Handler}, 
{Code::Value2, Handler::value2Handler}, 
}; 

要避免做大量的,如果的喜歡

if (value == Code::Value1) 
    value1Handler(); 
if (value == Code::Value2) 
    value2Handler(); 
if (value == Code::Value3) 
    value3Handler(); 

但我沒有找到一個很好的在Java中這樣做的方式,有可能嗎?

+1

開關的情況下?...... –

+3

@FastSnail我不喜歡開關的情況下...我不認爲這是非常乾淨 –

+0

如果你想基於輸入來執行某些方法,那麼我考慮命令模式可能是你的想法。 –

回答

4

正如我意識到的那樣,您希望將密鑰T與相應的操作Consumer<T>(或Function<K, V>,如果返回類型很重要)相關聯。

不幸的是,我們沒有地圖的文字,所以對於短期有可能產生HashMap子與初始塊:

Map<T, Consumer<T>> map = new HashMap<T, Consumer<T>>() {{ 
    put(k1, v -> {/* value handler 1 */}); 
    put(k2, v -> {/* value handler 2 */}); 
}}; 

作爲映射值,你可以通過你想要的操作用鍵執行。例如,

v -> System.out.println(v) 

如果這樣的動作是單一的,它可以通過一個方法參考代替:

System.out::println 

(在這裏,我理解的是valueXHandler的返回映射值,它們不只是消費者,所以Function<K, V>是我們的方式)

通常,我會寫一個映射器,鍵的值,並返回值:

public <K, V> V mapToValue(K key, Function<K, V> function) { 
    return function.apply(key); 
} 

它的用法很簡單:

map.put(k1, mapToValue(k1, k1 -> v1)); 
+0

番石榴和其他圖書館有地圖方便的建設者,這將使這個例子整潔。 – Basilevs

0

您可以用開關做到這一點:https://docs.oracle.com/javase/tutorial/java/nutsandbolts/switch.html

public class SwitchDemo { 
    public static void main(String[] args) { 

     int month = 8; 
     String monthString; 
     switch (month) { 
      case 1: monthString = "January"; 
        break; 
      case 2: monthString = "February"; 
        break; 
      case 3: monthString = "March"; 
        break; 
      case 4: monthString = "April"; 
        break; 
      case 5: monthString = "May"; 
        break; 
      case 6: monthString = "June"; 
        break; 
      case 7: monthString = "July"; 
        break; 
      case 8: monthString = "August"; 
        break; 
      case 9: monthString = "September"; 
        break; 
      case 10: monthString = "October"; 
        break; 
      case 11: monthString = "November"; 
        break; 
      case 12: monthString = "December"; 
        break; 
      default: monthString = "Invalid month"; 
        break; 
     } 
     System.out.println(monthString); 
    } 
} 
+4

OP更快,他評論說他不喜歡使用'switch'語句。 –

+0

一個不好的樣板例子,帶'String' /'int'字段的枚舉和一個靜態方法應該替代這個混亂(我沒有downvote) – Andrew

+3

我downvoted,不是因爲用'switch'回答,而是因爲你複製和從教程中粘貼示例,而不是提供一個簡單的示例或您自己的更相關的示例。看起來你看到了Fast Snail的帖子並採取行動,而沒有真正考慮到你的答案。對不起。如果你確定了答案,我將非常樂意收回downvote。 –

3

一個很好的(和大部分的時間,正確的)解決方案是使用多態。使用抽象類(或接口),其中有許多具有所需操作的不同實現的子項(相關函數)。 然後,具有一個工廠函數,根據該值返回(或生成)適當的對象類型,並運行其操作函數。

這可能不是一個非常小的程序正確的解決方案,但與真正的項目打交道時,這是一個非常好的做法(在設計模式,如國家,戰略和其他實現)。

+0

OP中已經使用了多態性。 – Basilevs

0

你可以採用3種方法,即: -

  1. 使用哈希映射利用一對存儲。

  2. 使用開關的情況下會爲了避免如果其他條件的多個檢查是有幫助的。

  3. 您可以很好地利用C++的OOP概念並且也使用多態(使用多個子或多個接口)。

+0

你能解釋一點嗎?對於1,顯示一些將lambda放在哈希映射中的代碼? OP似乎不喜歡'switch'語句。對於3,我完全無視代碼中的意思。 – Robert