0

The HashSet Set implementation allows the addition of null. Is there any Collection implementation that will not allow null? I know I can do a remove for the null on the HashSet, but I was wondering if I can restrict it.

public static void main(String[] args) {
    Set<String> testing = new HashSet<String>();
    testing.add(null);
    testing.add("test");

    for(String str : testing){

    }

  }


//TreeSet allows null as well
 public static void main(String[] args) {
    TreeSet<String> testing = new TreeSet<String>();
    testing.add(null);

    for(String str : testing){
      System.out.println("testing");
    }

  }
c12
  • 9,557
  • 48
  • 157
  • 253
  • A `TreeSet` does not accept `null`. – Sotirios Delimanolis Jan 06 '14 at 19:13
  • Are you looking for any `Collection` or just `Set` implementation? – Sotirios Delimanolis Jan 06 '14 at 19:25
  • @SotiriosDelimanolis a Set implementation – c12 Jan 06 '14 at 19:27
  • @SotiriosDelimanolis TreeSet allows nulls, see updated question. – c12 Jan 06 '14 at 19:27
  • It'll fail if you try to run it, with a `NullPointerException`. – Sotirios Delimanolis Jan 06 '14 at 19:28
  • @SotiriosDelimanolis I did run it and its prints out testing – c12 Jan 06 '14 at 19:29
  • Every implementation for SET has different purposes and pros/cons. If your starting with HashSet it means you want a list of Unique Values. If you want a HashMap it means you want key/value pairs. And a TreeMap means you want your key/value pairs to be ordered by Key. Each Data Structure has a specific purpose. – Menelaos Jan 06 '14 at 19:31
  • What Java version are you using? [It fails for Java 7.](http://ideone.com/Gnqbty) – Sotirios Delimanolis Jan 06 '14 at 19:31
  • @SotiriosDelimanolis you are right. I also got NullPointerException while running the program using TreeSet. – Qadir Hussain Jan 06 '14 at 19:34
  • It depends on java version – c12 Jan 06 '14 at 19:40
  • It shouldn't. The javadoc says it will throw a `NullPointerException`. Please double check your code. – Sotirios Delimanolis Jan 06 '14 at 19:40
  • @SotiriosDelimanolis if you only have one element and its null in a TreeSet and don't add anything to the TreeSet after it will not throw a NPE – c12 Jan 06 '14 at 19:56
  • @c12 How are you adding that first `null` element? You can't add a `null` to a `TreeSet`. The underlying `TreeMap` will try to compare the `key` to itself, throwing a `NullPointerException` when trying to invoke the `compareTo` method on a `null` reference. – Sotirios Delimanolis Jan 06 '14 at 20:01
  • @c12 [It seems you are correct.](http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java/util/TreeMap.java#TreeMap.put%28java.lang.Object%2Cjava.lang.Object%29) The `put` method `null` check is commented out. I would either upgrade or try the other collection types in my answer. – Sotirios Delimanolis Jan 06 '14 at 20:10

4 Answers4

2

A TreeSet is appropriate for your requirement. Its add(Object) method javadoc states

Throws:

NullPointerException - if the specified element is null and this set uses natural ordering, or its comparator does not permit null elements

in both Java 6 and Java 7.

Also, if you are looking for Collection implementations (rather than Set implements), there are others.

Community
  • 1
  • 1
Sotirios Delimanolis
  • 274,122
  • 60
  • 696
  • 724
0

If you want to use HashSet, but with that restriction for no null, you could also create a class extending HashSet.

Example:

public class HashSetNullLess<E> extends HashSet<E> {

    public boolean add(E e) {
            if(e==null)
            return false;  //Or throw unsupported exception message

            return super.add(e);
    }
}

This should pretty much take care of the problem as I checked the code of HashSet.java and even the constructors accepting collections lead to the add method via addAll in AbstractCollection.java

See:

public boolean addAll(Collection<? extends E> c) {
        boolean modified = false;
        for (E e : c)
            if (add(e))
                modified = true;
        return modified;
    }
Menelaos
  • 23,508
  • 18
  • 90
  • 155
0

I agree with SotiriosDelimanolis. I tried to run this code in JDK 7.

public class Test {

    public static void main(String arg[]) {

        TreeSet<String> set = new TreeSet<String>();
        set.add(null);
        set.add("Test");
        System.out.println(set);
    }
}

But got the following error:

Exception in thread "main" java.lang.NullPointerException

I think using your requirement will be fulfilled.

Pang
  • 9,564
  • 146
  • 81
  • 122
Qadir Hussain
  • 1,263
  • 1
  • 10
  • 26
-1
  • Consider to wrap Hashtable class. It does not allow nulls, however it implements Map interface. You can do this in a way as HasSet wraps HashMap. Take into account Hashtable is synchronized.

  • Use next, but it is a really implicit and could make code reading harder

        HashSet<String> set = new HashSet<String>() {
        @Override
        public boolean add(String s) {
            if(s == null)
                throw new NullPointerException();
            return super.add(s);
        }
    };
    
  • Use TreeMap, but before actual using it add just one element, because it accepts null only as initial element

Aleks F
  • 11
  • 1