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>?

3
  • Look at the keySet method Commented Aug 15, 2016 at 3: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<String>). ...why? What does that improve? Commented Aug 15, 2016 at 3:16
  • @Rogue Is that not obvious? So List<Integer>, List<SecurityManager> and List<Custom> would all be accepted without redefining several methods or using the heavy Generic syntax. Commented Aug 16, 2016 at 23:33

1 Answer 1

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.

Sign up to request clarification or add additional context in comments.

7 Comments

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.
static vs. non-static is a big debate I guess. Well, Map<String, ?> was what I was looking for. But if both compile and work, what does List<?> brings over List?
apparently List is here for legacy purpose. So I should probably use List<?>. stackoverflow.com/questions/6783316/list-vs-listobject
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
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.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.