2015-09-11 20 views
10

Tôi có tệp văn bản danh sách từ, tôi muốn có độ dài từ tối thiểu, tối đa và trung bình từ tệp đó.Cách lấy độ dài trung bình của từ bằng cách sử dụng Biểu thức Lambda

Tôi có một phương pháp dòng:

public static Stream<String> readWords(String filename) { 
    try { 
     BufferedReader reader = new BufferedReader(new FileReader(filename)); 
     Stream<String> stringStream = reader.lines(); 
     return stringStream; 
    } catch (IOException exn) { 
     return Stream.<String>empty(); 
    } 
} 

Trong phương pháp chính của tôi để kiểm tra tôi in max và min

System.out.println(readWords(filename) 
     .min(Comparator.comparing(s -> s.length())) 
     .get() 
     .length() 
); 
System.out.println(readWords(filename) 
     .max(Comparator.comparing(s -> s.length())) 
     .get() 
     .length() 
); 

nó hoạt động như mong đợi.

Câu hỏi:
Có thể lấy trung bình của độ dài từ như tôi đã làm trong phút và tối đa không? Trong cả hai trường hợp có hoặc không, làm thế nào để làm điều đó (chỉ như Lambda Expression)?

+0

bạn có thể sử dụng .reduce (0, (i, c) -> c + i.length()) và chia cho số dòng. –

+0

gợi ý: nếu tệp của bạn thực sự lớn và có nhiều dòng sử dụng thu thập thay vì giảm –

+0

@JoshuaK cảm ơn bạn vì sự đóng góp của bạn, tôi đã tìm thấy câu trả lời bên dưới –

Trả lời

13

Phương thức lines() sẽ giúp bạn có một luồng các dòng chứ không phải từ. Một khi bạn có Stream, gọi flatMap để thay thế cho dòng với dòng chữ, cung cấp các biểu thức lambda để tách ra dòng chữ:

Stream<String> stringStream = reader.lines().flatMap(line -> 
    Stream.of(line.split("\\s+")) 
); 

này sẽ sửa thực hiện lại maxmin. Nó cũng ảnh hưởng đến tính chính xác của bất kỳ phép tính trung bình nào bạn muốn thực hiện.

Để có được mức trung bình, bạn có thể gọi mapToInt để lập bản đồ các dòng chữ đến độ dài của họ (năng suất một IntStream), sau đó gọi average, mà trả về một OptionalDouble.

System.out.println(readWords(filename) 
    .mapToInt(s -> s.length()) // or .mapToInt(String::length) 
    .average() 
    .getAsDouble()); 
+0

Tại sao nó phải là 11? –

+0

Nó hoạt động thump lên, và tôi thích đầu vào của bạn liên quan đến .flatMap vv –

+3

làm thế nào về 'summaryStatistics()' - https://docs.oracle.com/javase/8/docs/api/java/util/stream/IntStream .html # summaryStatistics-- – ZhongYu

6

Dựa trên tài liệu chính thức về reductions

System.out.println(readWords(filename) 
       .mapToInt(String::length) 
       .average() 
       .getAsDouble() 
); 

Lưu ý rằng bạn có thể và có lẽ nên sử dụng tài liệu tham khảo phương pháp như String::length

+0

mã của bạn hoạt động quá thump up tôi đã chọn câu trả lời khác vì đầu vào Stream, câu trả lời của bạn là hợp lệ là tốt. –

+0

Tôi upvoted rgettman của câu trả lời cho cùng một lý do :-) Cảm ơn –

7

Sử dụng IntSummaryStatistics để có được những phút, tối đa và trung bình trong một đường chuyền.

IntSummaryStatistics summary = readWords(filename) 
    .collect(Collectors.summarizingInt(String::length)); 
System.out.format("min = %d, max = %d, average = %.2f%n", 
    summary.getMin(), summary.getMax(), summary.getAverage()); 
+1

Cảm ơn công trình này cũng chỉ cần kiểm tra nó. giơ ngón tay cái lên –

Các vấn đề liên quan