2017-10-10 449 views
6

以下代碼錯誤映射

String[] values = ... 
.... 
Map<String, Object> map = new HashMap<>(); 
for (int i = 0; i < values.length; i++) { 
    map.put("X" + i, values[i]); 
} 

通過的IntelliJ轉換爲:

Map<String, Object> map = IntStream.range(0, values.length) 
     .collect(Collectors.toMap(
       i -> "X" + i, 
       i -> values[i], 
       (a, b) -> b)); 

可縮短至

Map<String, Object> map = IntStream.range(0, values.length) 
      .collect(Collectors.toMap(
        i -> "X" + i, 
        i -> values[i])); 

的2個版本別編譯。

的IntelliJ,暗示存在與值I [i]的問題:

Incompatible types.
Required: int
Found: java.lang.Object

編譯器會抱怨:

Error:(35, 17) java: method collect in interface java.util.stream.IntStream cannot be applied to given types;
required: java.util.function.Supplier,java.util.function.ObjIntConsumer,java.util.function.BiConsumer
found: java.util.stream.Collector>
reason: cannot infer type-variable(s) R
(actual and formal argument lists differ in length)

任何人都可以解釋,爲什麼?

+0

什麼'值',你能否包括它的聲明?對IntelliJ的建議,似乎也不一致。只需在聲明和循環之間放置一個print map語句即可。它不會建議你*取代收藏*了。 – nullpointer

+1

String [] values = ... – msayag

+0

我想'Collector's不支持原語,這可能是爲什麼lambda轉換爲'Object',因爲'boxed()'修復了它。 –

回答

2

對智慧的建議如何在那裏工作不太確定,似乎並不一致。只要把申報和環路之間的

System.out.print(map); 

語句,然後它不會建議你用收集任何進一步的替換。


當使用IntStream#collect,編譯失敗對於實現collect方法需要三個指定的參數爲可視錯誤以及同時

Collectors.toMap(i -> "X" + i, i -> values[i]) 

會導致只有一個參數的原因類型Collector


更好地表達轉換方法是,雖然以

  • 要麼使用forEach

    Map<String, Object> map; 
    IntStream.range(0, values.length).forEach(i -> map.put("X" + i, values[i])); 
    
  • 或者使用boxed()IntStream轉換爲Stream<Integer>爲: -

    Map<String, Object> map = IntStream.range(0, values.length).boxed() 
          .collect(Collectors.toMap(i -> "X" + i, i -> values[i], (a, b) -> b)); 
    
  • 或者通過@Holger的建議,你能避免使用的forEach和拳擊開銷和修改結構,以利用IntStream.collect三ARG變異爲: -

    Map<String, Object> map = IntStream.range(0, values.length) 
          .collect(HashMap::new, (m,i) -> m.put("X"+i,values[i]), Map::putAll); 
    
+0

我會使用第一個。第二個,用'boxed'將導致'Integer'和int之間的盒子和解除盒子過多。 – Shirkam

+0

雖然你的解決方案是有效的,但他們不回答我的問題:爲什麼不編譯? – msayag

+0

@msayag編輯。雖然考慮日誌是不言自明的。另一方面,使用boxed將'IntStream'轉換爲'Stream',並且'collect'在該類中被重載以接受您的'Collector'傳遞。 – nullpointer