疯狂java


您现在的位置: 疯狂软件 >> 新闻资讯 >> 正文

Java中的HashSet


 

       HashSet集合 :不允许有重复的元素并且HashSet中元素的顺序是随机的,包括添加(add())和输出都是无序的。

  java.lang.Object

  |_ java.util.AbstractCollection

  |_ java.util.AbstractSet

  |_ java.util.HashSet

  例如:

  Java代码

  public static void main(String[] args) {

  Set set = new HashSet();

  set.add("aaa");

  set.add("bbb");

  set.add("ccc");

  set.add("ddd");

  set.add("aaa");

  set.add("ccc");

  for(String string:set){

  System.out.println("value="+string);

  }

  }

  输出结果:

  value=aaa

  value=ddd

  value=ccc

  value=bbb

  HashSet集合的一些常用操作:

  add(Object) :添加元素(Object);

  addAll(Collection) :向HashSet中添加一个集合(Collection);

  remove(Object) :删除一个指定的元素(Object);

  removeAll(Collection):删除一个指定的集合(Collection);

  size() :HashSet的容量,即HashSet内元素的个数;

  isEmpty() :判断HashSet是否为空,即[]或size()=0,返回true或false;

  contains(Object) :判断某个元素(Object)是否在HashSet中,返回true或false;

  containsAll(Collection):判断HashSet是否包含某个集合(Collection);

  clear() :清空HashSet,使得size()=0;

  toArray() :将HashSet转换成一个Object[];

  iterator() :构造一个HashSet迭代器,用于输出HashSet中的元素;

  遍历HashSet中的元素有两种方法,其一上面的代码已经介绍;

  其二就是迭代法:

  Java代码

  Iterator it = set.iterator();

  while (it.hasNext()) {

  System.out.println("value="+(String) it.next());

  }

  下面Object有点特殊情况,值得注意:

  由于Object拥有hashCode()和equals()两个方法,它认为具有相同的hashcode的对象才是同一个对象,即对同一个对象的引用。

  创建一个Student类:

  Java代码

  public class Student {

  private String name;

  private Integer age;

  public String getName() {

  return name;

  }

  public void setName(String name) {

  this.name = name;

  }

  public Integer getAge() {

  return age;

  }

  public void setAge(Integer age) {

  this.age = age;

  }

  }

  在main方法中测试:

  Java代码

  Set stuSet = new HashSet();

  Student s1 = new Student();

  s1.setName("zhangsan");

  s1.setAge(10);

  Student s2 = new Student();

  s2.setName("zhangsan");

  s2.setAge(10);

  stuSet.add(s1);

  stuSet.add(s2);

  System.out.println("Student数量:"+stuSet.size());

  输出结果是:

  Student数量:2

  重写Student类的hashCode和equals方法,在Student中添加下面的代码:

  Java代码

  //重写equals方法

  public boolean equals(Object o) {

  if (this == o) {

  return true;

  }

  if (!(o instanceof Student)) {

  return false;

  }

  final Student other = (Student) o;

  if (this.name.equals(other.getName())

  && this.age.equals(other.getAge())) {

  return true;

  } else {

  return false;

  }

  }

  //重写hashCode()方法

  public int hashCode() {

  int result = (name == null ? 0 : name.hashCode()) + (age == null ? 0 : age.hashCode());

  return result;

  }

  输出的结果:

  Student数量:1

  分析原因:name和age都是Student的成员变量是实例属性,根据内存的运行机制,new出来的两个对象都放到堆内存中,它们的name都是“zhangsan”,age都是10,而new出来的变量s1和s2都放在栈内存中并指向对应的对象,但是两个对象的hashCode和equals是不同的,所以放到HashSet中就是两个了。如果在Student中重写了hashCode和equals两个方法后,它们的hashCode和equals都相同了,那么将s1添加到HashSet中后,再添加s2时就重复不再添加了。此时,在内存中还是两个对象,但是在HashSet中就存了一个。