2014-10-26 4 views
4

Я пытаюсь создать карту, которая будет отображать строковые значения в функции. Вот интерфейс я создал (как в Java 8, но я не могу ее использовать):Создать карту с общим типом

interface Function<T, U> { 
    U apply(T t); 
} 

Теперь я создал метод сортировки для сортировки мой POJO на основе некоторых признаков:

public <U extends Comparable<U>> void sortPojoBy(Function<Pojo, U> f) { 
     Collections.sort(list, new Comparator<Book>() { 
      @Override 
      public int compare(Pojo first, Pojo second) { 
       return f.apply(first).compareTo(f.apply(second)); 
      } 
     }); 
} 

Тогда Я могу назвать это передавая анонимный класс функции для сортировки по атрибуту Я хочу, например:

sortBooksBy(new Function<Pojo, Double>(){ 
       @Override 
       public Double apply(Pojo p) { 
        return p.getPrice(); 
       } 
      }); 

Теперь у меня возникают проблемы, чтобы создать карту. В идеале я хотел бы что-то вроде этого:

Map<String, Function<Pojo, T extends Comparable<T>>> map = new HashMap<>(); 

Я знаю, что я не могу сделать что-то вроде этого, мой текущий обходной путь, чтобы создать карту с сырой функцией.

private Map<String, Function> map = new HashMap<>(); 
    { 
     map.put("price", new Function<Pojo, Double>(){ 
      @Override 
      public Double apply(Pojo t) { 
       return t.getPrice(); 
      }   
     }); 
     map.put("name", new Function<Pojo, String>(){ 
      @Override 
      public String apply(Pojo t) { 
       return t.getTitle(); 
      } 

     }); 
    } 

Мне нужна карта, потому что я получаю значения атрибута (имя, цена и т. Д.) Из конфигурационного файла JSON.

Итак, мой вопрос в том, есть ли способ создать мою карту, чтобы гарантировать, что тип T функции сопоставим с самим собой? (Я могу разобраться с обходным решением на данный момент, так как я его заполню вручную)

ответ

4

Один из способов - изменить его так, чтобы все функции обязательно вернули пригодное для использования сопоставимое в первую очередь. Другими словами, переместите аргумент, который у вас есть на Карте, к параметру Function.

interface Function<T, U extends Comparable<? super U>> { 
    U apply(T t); 
} 

Ваше объявление Карта теперь просто

Map<String, Function<Pojo, ?>> map = new HashMap<>(); 

Ваш общий метод sortPojoBy теперь также выполняет подстановочные захват U.

public <U extends Comparable<? super U>> void sortPojoBy(Function<Pojo, U> f); 

В качестве примечания стороны я немного изменил ваше объявление Comparable. T extends Comparable<? super T> - типичная форма. Это в случае, если T является подклассом аргумента, который он предоставил Comparable.

+0

Действительно приятно! Благодаря :) – user2336315

Смежные вопросы