0

How can I tell the compiler that I am sure that this generic type has the method get?

I have done a little bit of research, and let the T extends some interface might help. example1 example2

  1. But what is the exact interface I have to extends for the method get?

  2. How could I search for this interface in IDE? So that next time, I could avoid asking if it is some methods other than 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;
    }
    

Actually T is hashmap. But let us make it generic here.

Malt
  • 28,965
  • 9
  • 65
  • 105
Luk Aron
  • 1,235
  • 11
  • 34
  • `HashMap` implements the `Map` interface. This interface contains the `get` method. You could write `T extends Map<…, …>` or just `? extends Map<…, …>`. – MC Emperor Oct 29 '19 at 11:18
  • @MCEmperor Your answer inspires me that I can directly ` >` I just want the get method, so both works, right? – Luk Aron Oct 29 '19 at 12:18
  • Well, first, you should then use `Map` instead of `HashMap`, this is called [to program to an interface](https://stackoverflow.com/questions/383947/what-does-it-mean-to-program-to-an-interface). Second, you cannot just "cherry pick" a single method (e.g. `get`) to be implemented in some type; instead, you define the type which contains the method. – MC Emperor Oct 29 '19 at 12:35
  • It all depends on what exactly you want to achieve, and why you want to use generics at all. – MC Emperor Oct 29 '19 at 12:37
  • Oh, and note that the `Date` class is obsolete; you should instead use classes from the `java.time` package. – MC Emperor Oct 29 '19 at 12:39

2 Answers2

1

You have three choices:

  1. Use an interface such as Map which has the get() method. This however would limit T to be a Map and not anything with a get method.

  2. Use a custom interface that has the get() method, but since Java doesn't have duck typing, you'd need to extend the HashMap so it'll implement the custom interface, which isn't very convenient, especially if you're getting the HashMap from elsewhere.

  3. Finally, you could have the user to supply a function as a parameter. Maybe something like Function<String, Date>. For a HashMap, it will simply be the get() method for HashMap, but for other data types, it can be something else.

    Your function would be something like: private static <T> ArrayList<T> trimstartend(ArrayList<T> rows,Date startdate ,Date endDate, Function<String, Date> dateGetter)

    And to get the Date using the String, you'd have to call dateGetter.apply("Date").

Malt
  • 28,965
  • 9
  • 65
  • 105
0

Create an interface (e. g. Gettable), and write T extends Gettable.

OK, as @Malt points out, if a class doesn't implement this interface, extend it so that the new class does:

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);
    }
}
Lev Leontev
  • 2,538
  • 2
  • 19
  • 31