2017-01-16 3 views
3

Я новичок в функциональном программировании в java 1.8. У меня есть простой цикл, как код ниже:Java 8: Карта вместо простой петли

File folder = new File("./src/renamer/Newaudio"); 
File[] listOfFiles = folder.listFiles(); 

for (int i = 0; i < listOfFiles.length; i++) { 
    System.out.println("Here is file number: " + i); 
} 

Я собираюсь изменить верхний for loop к функциональной форме, используя функцию стрелки (например, лямбда).

listOfFiles.map((file) = > { 
     System.out.println("Here is file number: " + i); 
}); 

К сожалению, он жалуется:

Cannot invoke map((<no type> file) -> {}) on the array type File[] 

Почему я получаю эту ошибку? как я могу разрешить это?

Я хотел бы узнать о Lambda, поэтому я не заинтересован в Еогеасп

+7

Используйте '.forEach' вместо' .map'. Обратите внимание, что вы можете использовать 'Files.list (Paths.get (" ./ src/renamer/Newaudio ")). ForEach (...)' для прямого перехода в Stream API. – aioobe

+2

Что такое 'i' в вашей лямбде? –

+6

Если вы используете Java 8, ** Не используйте класс 'File' **. Он устарел и должен быть положен на отдых. Используйте «Путь» и «Файлы». – RealSkeptic

ответ

4

folder.listFiles() должны быть обернуты с Optional.ofNullable, чтобы предотвратить от NullPointerException. Он может возвращать null, если данное имя пути не обозначает каталог или возникает ошибка ввода-вывода.

Stream.of(ofNullable(folder.listFiles()). 
      orElseThrow(() -> new IllegalArgumentException("It's not a directory!"))) 
     .forEach(f -> {}); 

где метод forEach мог принять эти аргументы:

(1) анонимный класс

new Consumer<File>() { 
    public @Override void accept(File file) { 
     System.out.println(file); 
    } 
} 

(2) израсходованы лямбда-выражения

(File f) -> { System.out.println(f); } 
(f) -> { System.out.println(f); } 

(3) упрощается лямбда-выражения

f -> { System.out.println(f); } 
f -> System.out.println(f) 

(4) метод опорного

System.out::println 
+0

, когда я использовал формат несколько линий лямбда ** (ф -> {system.out.pringlin()}) ** он жалуется, что Синтаксическая ошибка, вставить "AssignmentOperator Expression", чтобы завершить \t Expression \t - The левая сторона присваивания должна быть переменной – Salman

+1

@Salman: класс 'System' начинается с верхнего регистра' S', метод 'println', а не' pringlin', и должна быть точка с запятой после заявления. – Holger

+1

@Andrew Tobilko: 'forEach' (не' foerEach') может принимать более четырех этих аргументов. Именованный класс, реализующий 'Consumer', также работает, как и любое другое выражение, приводящее к экземпляру этого типа, например, чтение переменной, содержащей существующий экземпляр, или вызов фабричного метода. И вы можете передать «null», компилятор не будет возражать, хотя результат предсказуемо мало используется ... – Holger

4
IntStream.range(0, listOfFiles.length).forEach(file -> { 
    System.out.println(file); 
}); 
+3

Примечание: исходный код OP не печатал имена файлов, а только цифры. –

5

Вы можете использовать IntStream.range для печати номера файлов только

IntStream.range(0,listOfFiles.length).forEach(System.out::println); 

или для print Содержание массива вы можете использовать

Arrays.stream(listOfFiles).forEach(System.out::println); 

Компилятор преобразует вашу ссылку метод в лямбда-выражения во время компиляции, так это

Arrays.stream(listOfFiles).forEach(System.out::println); 

будут преобразованы в этот

=> Arrays.stream(listOfFiles).forEach(i->System.out.println(i)); 

С лямбда вы можете использовать затраченную лямбда {} а

=> Arrays.stream(listOfFiles).forEach(i->{ 
     if (!i.isHidden()) { // don't print hidden files 
      System.out.println(i);    
     } 
    }); 

So listFiles возвращается null файлов не является каталогом, и для простоты можно просто поставить галочку в первую очередь

File folder = new File("./src/renamer/Newaudio"); 
    if (folder.isDirectory()) { 
     File[] listOfFiles = folder.listFiles(); 
     Arrays.stream(listOfFiles).forEach(i->System.out.println(i));   
    } 

Ссылка

Lambda and Method reference concise details

+0

Мне нравится узнать об Лямбда, поэтому мне не интересно, для foreach – Salman

+1

@Salman Метод forEach принимает выражение лямбда. – hoat4

+5

@ Салман, похоже, вы неправильно поняли, что такое «Лямбда». Лямбда является параметром метода 'map' или' forEach', а не самого метода 'map'. –