Why set is not allowed duplicate value, which kind

2020-08-14 09:59发布

I am new to java, i know set is not allowed duplicate value but i don't know why set is not allowed duplicate value, Actually i am doing practically,

Declared one set and add duplicate value but no kind of error is occurring, no compile time error, no run time. why?

标签: java
10条回答
做自己的国王
2楼-- · 2020-08-14 10:27

The meaning of "sets do not allow duplicate values" is that when you add a duplicate to a set, the duplicate is ignored, and the set remains unchanged. This does not lead to compile or runtime errors: duplicates are silently ignored.

You can tell that a value is a duplicate by checking the result of add, like this:

Set<String> testSet = new HashSet<String>();
boolean first = testSet.add("hello");
System.out.println(first);             // Prints "true"
boolean second = testSet.add("hello");
System.out.println(second);            // Prints "false"
查看更多
冷血范
3楼-- · 2020-08-14 10:27

Set is not allowed to store duplicated values by definition. If you need duplicated values, use a List. As specified on the documentation of the interface, when you try to add a duplicated value, the method add returns false, not an Exception.

http://docs.oracle.com/javase/7/docs/api/java/util/Set.html

查看更多
叛逆
4楼-- · 2020-08-14 10:30

Because that's how sets are defined. An element can only exist once in a set, but that doesn't mean trying to add it a second time should be an error. It's just a no-op. This is fairly clear from the documentation, for instance, for Set#add:

Adds the specified element to this set if it is not already present (optional operation). ... If this set already contains the element, the call leaves the set unchanged and returns false. In combination with the restriction on constructors, this ensures that sets never contain duplicate elements.

Among other things, this lets you happily add to sets without worrying, and know that the result will only ever have unique values in it.

Declared one set and add duplicate value but no any kind of error are occur, no compile time error no run time. Why?

Because it's not an error. But note that you did (or could have) received an indication that the value was already present: The add method's return value (see link above) tells you: "true if this set did not already contain the specified element"

查看更多
狗以群分
5楼-- · 2020-08-14 10:31

Internally SET store element using HASHTABLE ...HASHTABLE is a structure of Key value pairs..Here what the values passed by the SET is treated as Keys of HASHTABLE Internally. keys are unique cannot be duplicated. That is the reason if you pass any duplicate value it return false and does not added to the SET ...

If the adding element return true it will added into SET...Else it return False, that why it won't give any compilation or runtime error and it wont be added to SET

查看更多
趁早两清
6楼-- · 2020-08-14 10:31

So it is well known fact that Set is not allowing duplicate or equal objects but equality of the objects will be taken care by the programmer by giving the desired implementation of equals() and hashCode() methods. if we are not implementing these two methods set will even allow duplicates also. In hash based collections in java, first hashCode() method called and then equals() method called if required to check the equality of the objects. ,so bottom line is Set is using Map functionality internally and set values are inserted as keys inside this map internally and map is not allowing duplicate keys, You can also check the HashSet.java class from Java API where you can find similar map which is actually doing all the things.

Here is small code sample:

class Employee {
    private static int equalsCounter;
    private static int hashCodeCounter;
    private String name;
    private int age;

    public Employee() {
        super();
    }

    public Employee(String name, int age) {
        this.name = name;
        this.age = age;

    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "Employee [name=" + name + ", age=" + age + "]";
    }

    @Override
    public int hashCode() {
        hashCodeCounter++;
        System.out.println("hashCode() invoked : "+hashCodeCounter+" time");
        final int prime = 31;
        int result = 1;
        result = prime * result + age;
        result = prime * result + ((name == null) ? 0 : name.hashCode());
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        equalsCounter++;
        System.out.println("equals() invoked: "+equalsCounter+" time");
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Employee other = (Employee) obj;
        if (age != other.age)
            return false;
        if (name == null) {
            if (other.name != null)
                return false;
        } else if (!name.equals(other.name))
            return false;
        return true;
    }
}

public class Main {

    public static void main(String[] args) {
        Set<Employee> mySet  = new HashSet<Employee>();
        Employee e1 = new Employee("aaa", 30);
        Employee e2 = new Employee("aaa", 30);
        Employee e3 = new Employee("aaa", 30);
        mySet.add(e1); // HashCode() called and equals() not called
        mySet.add(e2);// HashCode() called and equals() also called
        mySet.add(e3);// HashCode() called and equals() also called
        System.out.println(mySet.size());
    }
}
查看更多
闹够了就滚
7楼-- · 2020-08-14 10:32

Thanks to A2A..

When you pass a duplicate element in the add method of set object, It'll return false and doesn't add it to the set as the element is already present.

Set<Object> set = new HashSet<Object>();
set.add("test");
set.add("test");

If you look at the implementation of HashSet then it looks like following.

public HashSet() {
        map = new HashMap<>();
    }

Means HashSet internally creates an object of HashMap.

public boolean add(E e) {
        return map.put(e, PRESENT)==null;
    }

If you look at the add method parameter e, then your passed value (test) will be consider as a key in the map and the PRESENT is the dummy object passed as a value.

HashMap put method returns the following

 1. null, if the key is unique and added to the map
 2. Old value of the key, if key is duplicate

So, when you are adding test element for the first time, HashMap will add the element and return null after that your add method of set will return true. If you add the test element for 2nd time then your HashMap will return Old Value of the Key then in add method of your set will return false as OldValue != null

Hope it'll be helpful..!!

查看更多
登录 后发表回答