2015-09-02 12 views
6

Tôi đã sử dụng cấu trúc dữ liệu Counter() trong Python làm kho khóa-giá trị cho phép tôi sắp xếp các đối tượng theo giá trị của chúng bằng phương pháp most_common. Thông tin thêm here.Truy cập Python thay thế cho Java

Có cấu trúc dữ liệu tương tự nào cho ngôn ngữ Java không? Ví dụ, tôi đã thấy nhiều câu trả lời liên quan tập trung vào phân loại HashMaps hoặc TreeMaps theo cấu trúc dữ liệu không được xác định ban đầu cho mục đích đó. Trong trường hợp của tôi, tôi thường cần phải giữ các bộ đếm đối tượng và sau đó chọn các đối tượng phổ biến nhất hoặc các đối tượng có điểm số cao nhất (các truy vấn N-Top). Tuy nhiên, nó là khó khăn cho tôi vì tôi cần phải chèn vào một HashMap và sau đó sắp xếp hoặc sử dụng nhiều cấu trúc dữ liệu.

+0

Có thể những gì bạn đang tìm kiếm nằm trong câu trả lời của câu hỏi [This] (http://stackoverflow.com/questions/2864840/treemap-sort-by-value?lq=1). –

Trả lời

4

Từ here:

The Counter lớp cũng tương tự như túi hoặc multisets bằng các ngôn ngữ khác.

Java không có lớp Multiset hoặc tương tự. Guava có bộ sưu tập MultiSet, thực hiện chính xác những gì bạn muốn.

Trong Java thuần túy, bạn có thể sử dụng một bản đồ và phương pháp hợp nhất mới:

final Map<String, Integer> counts = new HashMap<>(); 

counts.merge("Test", 1, Integer::sum); 
counts.merge("Test", 1, Integer::sum); 
counts.merge("Other", 1, Integer::sum); 
counts.merge("Other", 1, Integer::sum); 
counts.merge("Other", 1, Integer::sum); 

System.out.println(counts.getOrDefault("Test", 0)); 
System.out.println(counts.getOrDefault("Other", 0)); 
System.out.println(counts.getOrDefault("Another", 0)); 

Output:

2 
3 
0 

Bạn có thể quấn hành vi này trong một lớp học trong một vài dòng mã:

public class Counter<T> { 
    final Map<T, Integer> counts = new HashMap<>(); 

    public void add(T t) { 
     counts.merge(t, 1, Integer::sum); 
    } 

    public int count(T t) { 
     return counts.getOrDefault(t, 0); 
    } 
} 

Và sử dụng nó như thế này:

final Counter<String> counts = new Counter<>(); 

counts.add("Test"); 
counts.add("Test"); 
counts.add("Other"); 
counts.add("Other"); 
counts.add("Other"); 

System.out.println(counts.count("Test")); 
System.out.println(counts.count("Other")); 
System.out.println(counts.count("Another")); 

Output:

2 
3 
0 
1

Dưới đây là một lớp mà có vẻ như nó thực hiện đủ các Counter để làm những gì bạn muốn.

static class Counter<T> { 

    final ConcurrentMap<T, Integer> counts = new ConcurrentHashMap<>(); 

    public void put(T it) { 
     add(it, 1); 
    } 

    public void add(T it, int v) { 
     counts.merge(it, v, Integer::sum); 
    } 

    public List<T> mostCommon(int n) { 
     return counts.entrySet().stream() 
       // Sort by value. 
       .sorted((e1, e2) -> Integer.compare(e1.getValue(), e2.getValue())) 
       // Top n. 
       .limit(n) 
       // Keys only. 
       .map(e -> e.getKey()) 
       // As a list. 
       .collect(Collectors.toList()); 
    } 
} 

public void test() { 
    Counter<String> c = new Counter<>(); 
    String[] numbers = {"Zero", "One", "Two", "Three", "Four", "Five", "Six"}; 
    for (int i = 0; i < numbers.length; i++) { 
     c.add(numbers[i], i); 
    } 
    System.out.println(c.mostCommon(3)); 
} 

Nó sử dụng chức năng Java 8.