Java 为什么设置不允许重复值,它们背后使用了哪种机制?
我是java新手,我知道集合不允许重复值,但我不知道为什么集合不允许重复值,实际上我是在实际操作Java 为什么设置不允许重复值,它们背后使用了哪种机制?,java,Java,我是java新手,我知道集合不允许重复值,但我不知道为什么集合不允许重复值,实际上我是在实际操作 声明一个集合并添加重复值,但没有发生任何类型的错误,没有编译时错误,也没有运行时错误为什么?因为集合就是这样定义的。一个元素在一个集合中只能存在一次,但这并不意味着尝试第二次添加它应该是错误的。这只是一个禁忌。从文档中可以很清楚地看到,例如: 如果指定的元素尚未存在,则将其添加到此集合(可选操作)。。。如果此集合已经包含元素,则调用将保持集合不变并返回false。结合对构造函数的限制,这可以确保集合
声明一个集合并添加重复值,但没有发生任何类型的错误,没有编译时错误,也没有运行时错误为什么?因为集合就是这样定义的。一个元素在一个集合中只能存在一次,但这并不意味着尝试第二次添加它应该是错误的。这只是一个禁忌。从文档中可以很清楚地看到,例如: 如果指定的元素尚未存在,则将其添加到此集合(可选操作)。。。如果此集合已经包含元素,则调用将保持集合不变并返回false。结合对构造函数的限制,这可以确保集合中不包含重复的元素 除此之外,这让您可以轻松地添加到集合中,而无需担心,并且知道结果中只有唯一的值 声明一个集合并添加重复值,但没有发生任何类型的错误,没有编译时错误,也没有运行时错误。为什么? 因为这不是一个错误。但请注意,您确实(或可能)收到了一个指示,表明该值已经存在:
add
方法的返回值(请参见上面的链接)告诉您:“true
如果此集合尚未包含指定的元素”“集合不允许重复值”的含义是,当您向集合添加重复值时,重复项将被忽略,且集合保持不变。这不会导致编译或运行时错误:重复项会被忽略
通过检查add
的结果,可以判断某个值是重复的,如下所示:
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"
Set testSet=new HashSet();
boolean first=testSet.add(“hello”);
System.out.println(第一个);//打印“真实”
布尔秒=testSet.add(“hello”);
System.out.println(秒);//打印“假”
Set(Oracle文档)
不包含重复元素的集合。更正式地说,集合不包含e1和e2元素对,因此e1.equals(e2)最多包含一个空元素。正如它的名字所暗示的,这个接口为数学集合抽象建模
见:
集合(数学)-引用自
在数学中,集合是不同对象的集合,它本身被视为一个对象
添加方法
根据接口的文档,如果元素不存在,则添加元素。否则,一切都不会改变
布尔加法(E):
如果指定的元素尚未存在,则将其添加到此集合(可选操作)。如果此集合已经包含元素,则调用将保持集合不变并返回false
示例实现代码:HashSet
/**
*如果指定的元素尚未存在,则将其添加到此集合。
*更正式地说,如果
*此集合不包含元素e2,因此
*(e==null?e2==null:e.equals(e2))。
*如果此集合已经包含该元素,则调用将离开该集合
*未更改并返回false。
*
*@param e要添加到此集合的元素
*@如果此集合尚未包含指定的
*元素
*/
公共布尔加法(E){
返回map.put(e,PRESENT)=null;
}
集合不允许按定义存储重复的值。如果需要重复的值,请使用列表。如接口文档所述,当您尝试添加重复值时,add
方法返回false,而不是异常
“集合是不同对象的集合”
创建集合时,根据定义,集合中只能有唯一的对象。添加同一对象两次不会更改集合,因为元素/对象已在集合中。这是预期的行为。此行为非常有用的一个示例是,希望从元素集合中查找唯一的元素(即删除重复项).内部SET使用HASHTABLE存储元素。HASHTABLE是键值对的结构。在这里,SET传递的值在内部被视为HASHTABLE的键。密钥是唯一的,不能重复。这就是如果您传递任何重复值,它将返回false,并且不会添加到集合中的原因
如果adding元素返回true,它将被添加到集合…否则它将返回False,这就是为什么它不会给出任何编译或运行时错误,并且不会被添加到集合除了上述答案之外,下面是SET不允许重复元素的原因: 当您调用set的add(E)方法时,它在内部调用HashMap的put(E,E)方法,如下所示:
public boolean add(E e) {
return map.put(e, PRESENT)==null;
}
因此,要添加到set/HashSet的元素在内部作为键添加到Map中。因为我们需要将一些值与中的键相关联,所以每次都会传递虚拟值(newobject())(因为映射可以包含多个重复值)
现在如果仔细检查返回映射,put(e,PRESENT)==null添加(e,e)方法的代码>。有两种可能:
如果map.put(k,v)返回null,那么
map.put(e,PRESENT)==null代码>将返回true,并添加元素
如果map.put(k,v)返回键的旧值,则
map.put(e,PRESENT)==null代码>将返回false,并且不会添加元素
希望这将有助于理解清楚。多亏了A2A
当您在set对象的add方法中传递一个重复的元素时,它将返回false,并且不会将其作为
public boolean add(E e) {
return map.put(e, PRESENT)==null;
}
Set<Object> set = new HashSet<Object>();
set.add("test");
set.add("test");
public HashSet() {
map = new HashMap<>();
}
public boolean add(E e) {
return map.put(e, PRESENT)==null;
}
1. null, if the key is unique and added to the map
2. Old value of the key, if key is duplicate
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());
}
}