2016-09-01 2 views
2

Я писал фрагмент кода, в котором у меня была строка [], и метод, который принимает эту строку [], и возвращает Byte [], поддерживая пару строковых байт с положением, в котором некоторые из байтов могут быть пустыми. В конце концов, я должен преобразовать Byte и получить карту с ключом как строку из String [] и значение как возврат преобразования. Это, как я реализовал то же самое в Java 8 потоков:IntStream.boxed() vs for loop | Производительность

IntStream.range(0, productReferences.length) 
      .filter(index -> (null!= productsPrice[index])).boxed() 
      .collect(Collectors.toMap(position -> productReferences[position], 
        position ->callSomeMethod(productsPrice[position]))); 

где productReference является String [] и продуктовОбработка [] является байт [] массив.

Теперь вопрос заключается в методе IntStream.boxed(). Внутри он помещает int в Integer так, чтобы он возвращал Stream, который, по моему мнению, является более дорогостоящей операцией.

Другой способ будет использовать Java для цикла

for(int i=0;i<productReferences.length; i++){ 
    if (productsPrice[index]==null) continue; 
    //other code 
} 

Каков наилучший способ обработки такого рода сценария? Я понимаю причину создания IntStream, но если я действительно могу иметь индекс в методе сбора без метода boxed(), тем самым избегая бокса?

+6

Преждевременная оптимизация - это корень всего зла - если вам не нужна эта дополнительная производительность, придерживайтесь того, что вам легче понять. – Mac70

+0

@ Mac70 Я полностью согласен с тем, что вы говорите, сэр. :-) Еще одним дополнением к котенку знаний всегда является +1. – piyushGoyal

ответ

4

Вы можете использовать операцию collect, которую у вас есть на IntStream, а не на бокс в Stream<Integer>.

IntStream.range(0, productReferences.length) 
     .filter(index -> productsPrice[index] != null) 
     .collect(
      HashMap::new, 
      (m, i) -> m.put(productReferences[i], callSomeMethod(productsPrice[i])), 
      Map::putAll 
     ); 

Это не будет боксировать каждый индекс в качестве Integer после потребительской части коллектора занимает ObjIntConsumer; поэтому i в коде выше int. As Holger noted, исходный код, используя Collectors.toMap, генерирует исключение в случае дубликатов ключей, когда эта версия будет перезаписывать значение.

Вам все равно нужно будет сравнить два решения на ваших реальных данных, чтобы узнать, улучшит ли это.

+2

Предполагается, что это может быть потенциальное улучшение производительности - причина, по которой существует '' IntStream''. Но следует отметить, что существует семантическая разница. 'toMap' будет генерировать исключение, если есть дубликат ключа, тогда как этот вариант будет молча перезаписывать. Кстати, значение должно быть 'callSomeMethod (productsPrice [position])', а не 'productsPrice [position]'. – Holger

+0

Да. Это имеет смысл. Классический случай аккумулятора и финишера поставщика. И поскольку нет автоматического бокса, лучше, чем мой подход. Спасибо вам обоим! :-) – piyushGoyal

Смежные вопросы