2016-04-01 2 views
0

Когда я использую старый способ list.iterator() для выполнения рекурсии в каталоге, работает ниже код, но я не понимаю причину stackoverflow, которая появляется только тогда, когда я используйте лямбда согласно стилю Java 8.java.lang.StackOverflowError проблема с Lamba и рекурсия

private void walk(File file, int depth) { 
    if (depth >= maxDepth) 
     return;  
    List<File> files = file.isDirectory()?Arrays.asList(file.listFiles()):Arrays.asList(file); 
    filesStream.addAll(files.stream() 
         .filter(predicate1.and(predicate2)) 
         .collect(Collectors.toList())); 
    Stream<File> filteredDirectories = files.stream() 
              .filter(predicate3.and(predicate4)); 
    int currentDepth = ++depth; 
    filteredDirectories.forEach(f -> walk(f, currentDepth)); 
} 

Ниже StackTrace

java.lang.StackOverflowError 
at java.util.Collection.stream(Collection.java:581) 
at org.util.DirectoryManager.walk(DirectoryManager.java:192) 
at org.util.DirectoryManager.lambda$12(DirectoryManager.java:198) 
at org.util.DirectoryManager$$Lambda$10/1068824137.accept(Unknown Source) 
at java.util.stream.ForEachOps$ForEachOp$OfRef.accept(ForEachOps.java:183) 
at java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:175) 
at java.util.Spliterators$ArraySpliterator.forEachRemaining(Spliterators.java:948) 
at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:512) 
at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:502) 
at java.util.stream.ForEachOps$ForEachOp.evaluateSequential(ForEachOps.java:150) 
at java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(ForEachOps.java:173) 
at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234) 
at java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:418) 
at org.util.DirectoryManager.walk(DirectoryManager.java:198) 
at org.util.DirectoryManager.lambda$12(DirectoryManager.java:198) 
at org.util.DirectoryManager$$Lambda$10/1068824137.accept(Unknown Source) 
at java.util.stream.ForEachOps$ForEachOp$OfRef.accept(ForEachOps.java:183) 
at java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:175) 
at java.util.Spliterators$ArraySpliterator.forEachRemaining(Spliterators.java:948) 
at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:512) 
at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:502) 
at java.util.stream.ForEachOps$ForEachOp.evaluateSequential(ForEachOps.java:150) 
at java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(ForEachOps.java:173) 
at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234) 
at java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:418) 
at org.util.DirectoryManager.walk(DirectoryManager.java:198) 
at org.util.DirectoryManager.lambda$12(DirectoryManager.java:198) 
at org.util.DirectoryManager$$Lambda$10/1068824137.accept(Unknown Source) 
at java.util.stream.ForEachOps$ForEachOp$OfRef.accept(ForEachOps.java:183) 
at java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:175) 
... 
at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234) 
at java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:418) 
at org.util.DirectoryManager.walk(DirectoryManager.java:198) 
at org.util.DirectoryManager.lambda$12(DirectoryManager.java:198) 
at org.util.DirectoryManager$$Lambda$10/1068824137.accept(Unknown Source) 
at java.util.stream.ForEachOps$ForEachOp$OfRef.accept(ForEachOps.java:183) 
at java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:175) 
at java.util.Spliterators$ArraySpliterator.forEachRemaining(Spliterators.java:948) 
at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:512) 
at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:502) 
at java.util.stream.ForEachOps$ForEachOp.evaluateSequential(ForEachOps.java:150) 
at java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(ForEachOps.java:173) 
at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234) 
+1

Я запутался, почему вы делаете 'files.stream(). Фильтр (predicate1.and (predicate2))' дважды –

+1

что значение 'maxDepth ', и почему вы используете' Arrays.asList (файл) 'для одного файла? это явно вызовет повторную рекурсию с тем же параметром – njzk2

+0

«В качестве альтернативы» чему? Что ты пытаешься сделать*? Потому что вы в основном задаете [XY вопрос] (http://meta.stackexchange.com/a/66378) здесь. –

ответ

1

Вы рекурсию бесконечно. Если file не является каталогом, вы все равно проводите его снова. Убедитесь, что file является каталогом первой, что-то подобное,

if (file.isDirectory()) { 
    Stream<File> filteredDirectories = files.stream() 
      .filter(predicate1.and(predicate2)); 
    int currentDepth = ++depth; 
    filteredDirectories.forEach(f -> walk(f, currentDepth)); 
} 
+0

Я никогда не видел «рекурсию» переносимой. – shmosel

+1

Если вы не говорите о ком-то постоянно ругающемся – JamesENL