38

I am trying to create a Set of Strings which is filled with the keys from a Hashtable so a for-each loop can iterate through the Set and put defaults in a Hashtable. I am still learning Java but the way I am trying to do it isn't valid syntax. Could someone please demonstrate the proper way of doing this and explain why my way doesn't work and theirs does.

private Hashtable<String, String> defaultConfig() { Hashtable<String, String> tbl = new Hashtable<String, String>(); tbl.put("nginx-servers","/etc/nginx/servers"); tbl.put("fpm-servers","/etc/fpm/"); tbl.put("fpm-portavail","9001"); tbl.put("webalizer-script","/usr/local/bin/webalizer.sh"); tbl.put("sys-useradd","/sbin/useradd"); tbl.put("sys-nginx","/usr/sbin/nginx"); tbl.put("sys-fpmrc","/etc/rc.d/php_fpm"); tbl.put("www-sites","/var/www/sites/"); tbl.put("www-group","www"); return tbl; } //This sets missing configuration options to their defaults. private void fixMissing(Hashtable<String, String> tbl) { Hashtable<String, String> defaults = new Hashtable<String, String>(defaultConfig()); //The part in error is below... Set<String> keys = new Set<String>(defaults.keySet()); for (String k : keys) { if (!tbl.containsKey(k)) { tbl.put(k, defaults.get(k)); } } } 
3
  • 1
    should be new HashSet<String>(); Commented Sep 22, 2013 at 17:25
  • Hashtable is mostly obsolete - you should generally use HashMap instead. Commented Sep 22, 2013 at 17:54
  • possible duplicate of Cannot instantiate the type List<Product> Commented Jul 17, 2014 at 12:20

3 Answers 3

78

Set is not a class, it is an interface.

So basically you can instantiate only class implementing Set (HashSet, LinkedHashSet orTreeSet)

For instance :

Set<String> mySet = new HashSet<String>(); 
Sign up to request clarification or add additional context in comments.

3 Comments

@JonSkeet "Except that you wouldn't actually want to use raw types ..." Why not? To my understanding, a Set is perfect for 1. preventing duplicate entries 2. Checking if an entry exists in a collection as it's contains() method is simpler/faster than that of a List or Map.
@AgiHammerthief: That's not what raw types are. I suspect the original answer had Set mySet = new HashSet();. Those are raw types - no generic type arguments. I suspect the answer was then edited within 5 minutes, which means there's no record of that original version with raw types.
An interface defines what should be inside this object. A HashSet is an implementation of a Set interface so it contains the methods and properties that the Set interface defines.
2

Set is an interface. You cannot instantiate an interface, only classes which implement that interface.

The interface specifies behaviour, and that behaviour can be implemented in different ways by different types. If you think about it like that, it makes no sense to instantiate an interface because it's specifying what a thing must do, not how it does it.

Comments

0

HashMap's keySet() method already creates the set you need, so simply:

Set<String> keys = defaults.keySet(); 

This is a view of the keys in defaults, so its contents will change when changes are made to the underlying (defaults) map. Changes made to keys will be reflected in the map, as well, but you can only remove...not add...keys from the map.

If you need a copy of the keys that doesn't interact with the original map, then use one of the types suggested, as in:

Set<String> keys = new HashSet( defaults.keySet() ); 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.