2014-11-05 32 views

Trả lời

7

Một giải pháp:

public final class Foo 
{ 
    private static void printProperty(final Object key, final Object value) 
    { 
     System.out.println(key + ": " + value); 
    } 

    public static void main(final String... args) 
    { 
     System.getProperties().forEach(Foo::printProperty); 
    } 
} 

Rundown:

  • Properties kéo dài Hashtable<Object, Object> mà tự nó thực hiện Map<Object, Object>;
  • Map có phương thức .forEach() có đối số là BiConsumer;
  • BiConsumerfunctional interface;
  • phương pháp tĩnh printProperty() của lớp Foo xảy ra để có chữ ký giống như một BiConsumer<Object, Object>: "giá trị trở lại" của nó là void, số đầu tiên của nó là Object, số thứ hai của nó là Object;
  • do đó chúng tôi có thể sử dụng Foo::printProperty làm tham chiếu phương pháp.

Một phiên bản ngắn hơn sẽ là:

public final class ShorterFoo 
{ 
    public static void main(final String... args) 
    { 
     System.getProperties() 
      .forEach((key, value) -> System.out.println(key + ": " + value)); 
    } 
} 

Khi chạy, điều này sẽ không tạo sự khác biệt. Lưu ý suy luận kiểu trong ví dụ thứ hai: trình biên dịch có thể phỏng đoán rằng keyvalue thuộc loại Object. Một cách khác để viết những dòng này "lambda anonymous" sẽ là:

(Object key, Object value) -> System.out.println(key + ": " + value) 

(không như vậy) Side lưu ý: mặc dù nó là một chút lỗi thời, bạn thực sự muốn xem this video (có, đó là một giờ dài, có, nó là giá trị xem tất cả).


(không phải như vậy) Lưu ý bên 2: bạn có thể nhận thấy rằng Map's .forEach() mentions a default implementation; điều này có nghĩa là triển khai Map tùy chỉnh của bạn hoặc triển khai khác từ thư viện bên ngoài, sẽ có thể sử dụng .forEach() (ví dụ: số ImmutableMap s của Guava). Nhiều phương thức như vậy trên các bộ sưu tập Java tồn tại; đừng ngần ngại sử dụng những "phương pháp mới" này trên "chó già".

+0

Ý của bạn là gì "(không phải như vậy)"? –

+1

@KirkWoll sắp xếp trò chơi chữ; có nghĩa là, tôi cho rằng các ghi chú bên này quan trọng như câu trả lời chính nó – fge

3

@fge đã bỏ lỡ một phiên bản rất ngắn thừa nhận phụ thuộc vào việc triển khai toString của Map.Entry.

public class VeryShortFoo { 
    public static void main(String... args) { 
     System.getProperties().entrySet().forEach(System.out::println); 
    } 
} 
  • Ở đây, entrySet được xem trực tiếp và mỗi Map.Entry được in với một tham chiếu đến out.println.
  • Map.Entry việc triển khai toString thường trả lại getKey() + "=" + getValue().

Đây là một số khác tôi thích.

public class ElegantFoo { 
    public static void main(String... args) { 
     System.getProperties().entrySet().stream() 
      .map(e -> e.getKey() + ": " + e.getValue()) 
      .forEach(System.out::println); 
    } 
} 
  • Các entrySet được xem trực tiếp một lần nữa (lần này một cách rõ ràng với một cuộc gọi đến stream).
  • Stream#map thực hiện chuyển đổi 1: 1 từ các phần tử của một loại thành các phần tử khác. Tại đây, nó biến một số Stream<Map.Entry> thành Stream<String>.
  • Stream<String> được in.
+0

Một trong những tốt ... Trong thực tế, tôi thậm chí đã không cố gắng đó. Lưu ý ở đây là nó thực sự "gọi" phương thức '.forEach()' trên 'Set'. (Ngoài ra, câu hỏi tiếng Anh thuần túy: bạn sẽ không viết "thừa nhận" thay vì "thừa nhận"?) – fge

+0

Tôi có thể gợi ý rằng bạn làm nổi bật "tóm tắt" các đoạn mã của bạn như tôi đã làm không? – fge

0

Trong Java 8, lớp Properties thừa hưởng một phương pháp mới từ HashTable gọi forEach. Phương thức mới này chấp nhận các hàm (các giao diện chức năng) được chuyển cho nó làm đối số. Để cụ thể hơn, nó chấp nhận giao diện chức năng BiConsumer<T,U>. Phương thức chức năng của giao diện chức năng nàyaccept(T t, U u). Trong Java 8, tất cả các giao diện chức năng có thể được viết dưới dạng các biểu thức Lambda. Do đó, dưới đây là cách chúng tôi sẽ hiển thị tất cả các thuộc tính trong một cá thể Property:

Properties vmProps = System.getProperties(); 
vmProps.forEach((t,u) -> System.out.println("Property: " + t + "\nValue: " + u + "\n")); 
Các vấn đề liên quan