2016-03-23 6 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:はい、この共分散/反変分は扱いにくいです。 –