Reputation: 67
I cannot find a way to iterator over the SET below using wildcards. I have also tried to convert it like it is mentioned in Effective Java but still get compilation error.
public void testWildCardIteration() {
LinkedHashMap<String, ?> result = new LinkedHashMap<>();
Set<Map.Entry<String, ?>> entrySet = // entries....
iterHelper(entrySet, result);
}
private <E> void iterHelper(Set<Map.Entry<String, E>> entrySet , LinkedHashMap<String, E> result) {
for (Map.Entry<String, E> entry : entrySet) {
String tmpkey = entry.getKey();
if (tmpkey.startsWith("KEY")) {
result.put(entry.getKey(), entry.getValue());
}
}
}
Upvotes: 1
Views: 280
Reputation: 14611
You can use wildcards in the read only collection. But you will have to use a super
lower bounded wildcard applied to the collection to which you are writing.
In essence this should compile:
public void testWildCardIteration() {
LinkedHashMap<String, ? super Object> result = new LinkedHashMap<>(); // write collection
Set<Map.Entry<String, ?>> entrySet = new HashSet<>(); // read collection
iterHelper(entrySet, result);
}
private void iterHelper(Set<Map.Entry<String, ?>> entrySet, LinkedHashMap<String, ? super Object> result) {
for (Map.Entry<String, ?> entry : entrySet) {
String tmpkey = entry.getKey();
if (tmpkey.startsWith("KEY")) {
result.put(entry.getKey(), entry.getValue());
}
}
}
Here is a simple test which shows the code working:
public static void testWildCardIteration() {
LinkedHashMap<String, ? super Object> result = new LinkedHashMap<>();
Set<Map.Entry<String, ?>> entrySet = new HashSet<>();
entrySet.add(new AbstractMap.SimpleEntry<String, Object>("KEY", "BLAH"));
iterHelper(entrySet, result);
System.out.println(result);
}
private static void iterHelper(Set<Map.Entry<String, ?>> entrySet, LinkedHashMap<String, ? super Object> result) {
for (Map.Entry<String, ?> entry : entrySet) {
String tmpkey = entry.getKey();
if (tmpkey.startsWith("KEY")) {
result.put(entry.getKey(), entry.getValue());
}
}
}
public static void main(String[] args) {
testWildCardIteration();
}
This prints out:
{KEY=BLAH}
Upvotes: 1
Reputation: 131346
The E
method scoped is not required.
As it doesn't specify any bound, it uses Object
by default.
Instead, specify ?
as type of Entry.value
of entrySet
and specify Object
as type of Entry.value
of result
.
Note that you cannot specify ?
as type such as Set<?>
as you want to add not null
s in a collection. But with Object
such as Set<Object>
you can do it.
private void iterHelper(Set<Map.Entry<String, ?>> entrySet , LinkedHashMap<String, Object> result) {
for (Map.Entry<String, ?> entry : entrySet) {
String tmpkey = entry.getKey();
if (tmpkey.startsWith("KEY")) {
result.put(entry.getKey(), entry.getValue());
}
}
}
You can now invoke it :
LinkedHashMap<String, Object> result = new LinkedHashMap<>();
Set<Map.Entry<String, ?>> entrySet = ...;
iterHelper(entrySet, result);
Upvotes: 1