【问题标题】:How to call get method of a generic type?如何调用泛型类型的get方法?
【发布时间】:2019-10-29 11:10:05
【问题描述】:

如何告诉编译器我确定这个泛型类型有get方法?

我做了一些研究,让 T 扩展一些接口可能会有所帮助。 example1 example2

  1. 但是我必须为 get 方法扩展的确切接口是什么?

  2. 如何在 IDE 中搜索这个接口? 这样下次我就可以避免询问是否是 get 以外的其他方法

    private static <T> ArrayList<T> trimstartend(ArrayList<T> rows,Date startdate ,Date endDate){
    
    // if the date of current row is before the startdate, remove it
    for (Iterator<T> iterator = rows.iterator(); iterator.hasNext();) {
        T row = iterator.next();
        if ((Date)row.get("Date").before(startdate) ) {    // this line doesn't compile!  Unresolved method get 
            iterator.remove();
        }
    }
    
    // if the date of current row is after the enddate, remove it
    for (Iterator<T> iterator = rows.iterator(); iterator.hasNext();) {
        T row = iterator.next();
        if ((Date)row.get("Date").after(endDate)) {        // this line doesn't compile!   Unresolved method get
            iterator.remove();
        }
    }
    
    return rows;
    }
    

其实T就是hashmap。但让我们在这里通用。

【问题讨论】:

  • HashMap 实现了Map 接口。该接口包含get 方法。你可以写T extends Map&lt;…, …&gt; 或者只是? extends Map&lt;…, …&gt;
  • @MCEmperor 你的回答启发了我,我可以直接&lt;T extends HashMap&lt;...,...&gt; &gt; 我只想要get 方法,所以两者都有效,对吧?
  • 嗯,首先,您应该使用Map 而不是HashMap,这称为to program to an interface。其次,您不能只“挑选”一种方法(例如get)以某种类型实现;相反,您定义包含该方法的类型。
  • 这一切都取决于您究竟想要实现什么,以及您为什么要使用泛型。
  • 哦,请注意 Date 类已过时;您应该改用 java.time 包中的类。

标签: java generics intellij-idea methods


【解决方案1】:

你有三个选择:

  1. 使用具有get() 方法的接口,例如Map。但是,这会将 T 限制为 Map 而不是 get 方法。

  2. 使用具有get() 方法的自定义接口,但由于Java 没有duck typing,您需要扩展HashMap,以便它实现自定义接口,即不是很方便,特别是如果您从其他地方获得HashMap

  3. 最后,您可以让用户提供一个函数作为参数。也许像Function&lt;String, Date&gt; 这样的东西。对于HashMap,它只是HashMapget() 方法,但对于其他数据类型,它可以是别的东西。

    您的函数将类似于: private static &lt;T&gt; ArrayList&lt;T&gt; trimstartend(ArrayList&lt;T&gt; rows,Date startdate ,Date endDate, Function&lt;String, Date&gt; dateGetter)

    要使用String 获取Date,您必须调用dateGetter.apply("Date")

【讨论】:

    【解决方案2】:

    创建一个接口(例如Gettable),并写入T extends Gettable

    好的,正如@Malt 指出的那样,如果一个类没有实现这个接口,就扩展它以便新类实现:

    public interface Gettable {
        Object get(String key);
    }
    public class GettableHashMap<K, V> extends HashMap<K, V> implements Gettable {
        @Override
        public Object get(String key) {
            return super.get(key);
        }
    }
    

    【讨论】:

    • 只有HashMap 不会自己实现Gettable...
    • @Malt 你可以创建一个HashMap的子类来实现它
    • 是的。这就是为什么它应该在答案中。
    • 对不起,我应该写&lt;T extends Gettable&gt;&lt;T extends GettableHashMap&gt;
    • @Luk Aron 。但是不要使用 HashMap,而是使用 GettableHashMap。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-21
    • 2011-02-18
    • 2012-01-11
    • 1970-01-01
    • 1970-01-01
    • 2011-05-18
    相关资源
    最近更新 更多