0

This is a question about Java syntax. I am not stuck.

For lists, let's say I have a List of Strings.

List<String> mylist;

As long as I don't need to access the elements in my list, I can refer to this list as a List (versus List<String>).
So I can have a method looking like that:

public int listSize(List list) {
    return list.size();
}

Now let's assume I have a HashMap.

HashMap<String, String> myhash;

And a method accessing the key but never the value:

public boolean hashContainsKey(HashMap<String, String> hash, String key) {
    return hash.containsKey(key);
}

Is there a nice way to only specify the "key" part of the HashMap?
Something like HashMap<String>?

gabriel
  • 176
  • 1
  • 9
  • Look at the keySet method – Zymus Aug 15 '16 at 03:04
  • 2
    `As long as I don't need to access the elements in my list, I can refer to this list as a List (versus List).` ...why? What does that improve? – Rogue Aug 15 '16 at 03:16
  • @Rogue Is that not obvious? So ```List```, ```List``` and ```List``` would all be accepted without redefining several methods or using the heavy *Generic* syntax. – gabriel Aug 16 '16 at 23:33

1 Answers1

1

I wish your example is just something to demonstrate your idea instead of something you are going to write, as it is quite meaningless to write method like these.

One way is to use wildcard for the type param:

your first example should look like this

// Should be static in this example
public static int listSize(List<?> list) {
    return list.size();
}

and the other one should be:

// It is, imho, irrational to deal with HashMap specifically, 
// and again, this should be static
public static boolean mapContainsKey(Map<String, ?> map, String key) {
    return map.containsKey(key);
}

or even better:

public <T> static boolean mapContainsKey(Map<T, ?> map, T key) {
    return map.containsKey(key);
}

Little update on why use wildcard (List<?>) over raw type (List)

In OP's example, the difference may not be obvious. However they are not equivalent.

For example:

public void foo(List list1, List list2) {
  list1.addAll(list2);
}

The above is legal, but if you call it with foo(aStringList, anIntegerList);, the outcome will be disastrous: the String List will now contains Integers, everything messed up.

But if you write

public void foo(List<?> list1, List<?> list2) {
  list1.addAll(list2);
}

Although list1 and list2 allows any List<XXX> to pass in, without you explicitly telling the compiler that they are of the same type, compiler will assume the ? in list1 and the ? in list2 can represent different thing, and hence fail the compilation of list1.addAll(list2);, which avoid you writing stupid things like this.

Adrian Shum
  • 38,812
  • 10
  • 83
  • 131
  • any reason for the downvote? Wildcard is supposed to be the way in Java generics to let certain type parameter to match "anything", which is precisely what OP is asking for. – Adrian Shum Aug 16 '16 at 01:46
  • ```static``` vs. non-static is a big debate I guess. Well, ```Map``` was what I was looking for. But if both compile and work, what does ```List>``` brings over ```List```? – gabriel Aug 16 '16 at 23:37
  • apparently ```List``` is here for legacy purpose. So I should probably use ```List>```. http://stackoverflow.com/questions/6783316/list-vs-listobject – gabriel Aug 18 '16 at 22:24
  • In your case, the difference of raw type and wildcard may not be obvious. When you are dealing with, for example, more than 1 lists, it actually perform type checking. See my update – Adrian Shum Aug 19 '16 at 03:08
  • for the debate of `static`, I explicitly said it should be static **in this example**, which I don't think is anything debatable: it is obviously just working on the input param, and has nothing to do with the instance itself. – Adrian Shum Aug 19 '16 at 03:16
  • I agree it does not need to know the instance itself. But by using static we prevent inheritance, right? Poor benefit in this scenario, but we can imagine overriding the class to improve method performance for example. Cheers for the update btw. – gabriel Aug 19 '16 at 03:36
  • tho off topics: I don't agree that's a concern. In 99% of case you should take to decide whether it is static/non-static. It is simply semantically whether it is a method of an instance or not that should drive you to choose from static(i.e. class-level) or non-static (i.e. instance-level). Using inheritance for such purpose is even a weirder idea. – Adrian Shum Aug 19 '16 at 03:48