2016-03-23 54 views
3

我在代碼中嵌入了我的問題;我試圖通過編寫需要一個通用的Function簽名的方法(我認爲),以消除重複代碼:Java 8通用compareBy()方法簽名

import java.util.*; 
import java.util.function.*; 
import java.util.stream.*; 

class Sortable { 
    private String name; 
    private int id; 
    private long data; 
    Sortable(String name, int id, long data) { 
    this.name = name; 
    this.id = id; 
    this.data = data; 
    } 
    public String name() { return name; } 
    public int id() { return id; } 
    public long data() { return data; } 
    @Override 
    public String toString() { 
    return String.format("%-7s %-5d %d", name, id, data); 
    } 
} 

public class SortByMethod { 
    // Here's the method I want to create, in order 
    // to eliminate repetition. But what signature to use? 
    /* 
    public void sortBy(String by, List<Sortable> list, Function<???, ???> keyExtractor) { 
    System.out.println("--- Sorted By " + by + " ---"); 
    list.stream() 
     .sorted(Comparator.comparing(keyExtractor)) 
     .forEach(System.out::println); 
    } 
    */ 
    public static void main(String[] args) { 
    List<Sortable> list = Arrays.asList(
     new Sortable("Foo", 11, 991876), 
     new Sortable("Bar", 1, 991875), 
     new Sortable("Baz", 7, 991874), 
     new Sortable("Bingo", 19, 991873) 
    ); 
    System.out.println("--- Sorted By Name ---"); 
    list.stream() 
     .sorted(Comparator.comparing(Sortable::name)) 
     .forEach(System.out::println); 
    System.out.println("--- Sorted By ID ---"); 
    list.stream() 
     .sorted(Comparator.comparing(Sortable::id)) 
     .forEach(System.out::println); 
    System.out.println("--- Sorted By Data ---"); 
    list.stream() 
     .sorted(Comparator.comparing(Sortable::data)) 
     .forEach(System.out::println); 
    // Instead of the above repetitive code, I'd like to say: 
    /* 
    sortBy("Name", list, Sortable::name); 
    sortBy("ID", list, Sortable::id); 
    sortBy("Data", list, Sortable::data); 
    */ 
    } 
} 

我已經得到了一切工作,除了爲keyExtractor簽名。

回答

4

你的方法應該是這樣的:

static <T, U extends Comparable<? super U>> void sortBy(
    String column, 
    List<? extends T> list, 
    Function<? super T, ? extends U> keyExtractor) { 

    System.out.println("--- Sorted By " + column + " ---"); 
    list.stream() 
     .sorted(Comparator.comparing(keyExtractor)) 
     .forEach(System.out::println); 
} 

得到這個權利是簡單地去Comparator.comparing(),並複製他們的簽名粘貼仿製藥,因爲你必須履行自己的API限制的最快方法:

static <T,U extends Comparable<? super U>> Comparator<T> comparing(
    Function<? super T,? extends U> keyExtractor) 
+0

一旦我看到它完成,它是有道理的。困難的部分是實現如何去解決它。 – user1677663

+2

@ user1677663:是的,這個協變/逆變的東西很棘手。 –