Как использовать цикл в лямбда-функциях в JAVA?

#java #lambda #filter #java-stream

#java #лямбда #Фильтр #java-stream

Вопрос:

Я хочу создать FilenameFilter с помощью лямбда-функции.

Моя главная проблема в том, что я хочу ввести цикл внутри функции. Я пытался использовать фильтры, но я не могу создавать фильтры на основе внешнего списка.

Ниже приведен мой код:

     File targetDir = new File(path);
    FilenameFilter deleteFilter = new FilenameFilter() {
        @Override
        public boolean accept(File dir, String name) {
            for(String tag: pageTagsList){
                if(name.equals(tag))
                    return true;
            }
            return false;
        }
    };
    File[] foundFiles = targetDir.listFiles(deleteFilter);
  

То, что я хочу сделать, это что-то вроде этого:

 File[] foundFiles = targetDir.listFiles(
            (dir,name)->pageTagsList.stream()
            .filter(//code to filter here)
            .orElse(false)
            );
  

Есть ли правильный способ сделать это?

Комментарии:

1. Возможно, это надуманный пример, и смысл в том, чтобы знать, как выполнять итерацию в теле лямбда-кода в целом, но если нет, лучшим решением было бы использовать pageTagsSet тип Set<String> . Поиск в HashSet намного быстрее, чем перебор списка. Так (dir,name)->pageTagsList.contains(name) бы это сделал

Ответ №1:

Лямбда может быть любым блоком кода (хотя любые переменные, на которые ссылаются внутри него, должны быть окончательными). Для желаемого результата вы можете сделать что-то вроде следующего:

 File[] foundFiles = targetDir.listFiles((dir, name) -> pageTagsList.stream().anyMatch(name::equals));
  

Ответ №2:

Лямбда может содержать блок кода. Синтаксис такой:

 (params) -> {
    // Some code.

    for (Element elem : elements) {
        // Some code using elem.
    }

    return returnValue;
}
  

Ответ №3:

 List<String> tags = pageTagList
                   .stream()
                   .filter(t -> t.equals(name)).collect(Collectors.toList());
  

Если вам нужно объяснение чего-либо выше, просто спросите в комментарии. Я нахожу этот код самоописывающимся.

Ответ №4:

 @Override
public boolean accept(File dir, String name) {    
    return pageTagsList.stream()
        .filter(name::equals)
        .findAny()
        .isPresent()
}
  
  • Это просто демонстрация возврата true / false, ответ от Аарона Дэвиса самый элегантный

Комментарии:

1. На самом деле, самое элегантное решение pageTagsList.contains(name) . Начиная с Java 2…