下载安卓APP箭头
箭头给我发消息

客服QQ:3315713922

Set拥有是否与Collection完全相同的接口

作者:课课家教育     来源: http://www.kokojia.com点击数:842发布时间: 2016-02-22 10:37:25

标签: Java的对象Java程序java编程

大神带你学编程,欢迎选课

  Set拥有与Collection完全相同的接口,所以和两种不同的List不同,它没有什么额外的功能。相反,Set完全就是一个Collection,只是具有不同的行为(这是实例和多形性最理想的应用:用于表达不同的行为)。在这里,一个Set只允许每个对象存在一个实例(正如大家以后会看到的那样,一个对象的“值”的构成是相当复杂的)。

  Set(接口) 添加到Set的每个元素都必须是独一无二的;否则Set就不会添加重复的元素。添加到Set里的对象必须定义equals(),从而建立对象的唯一性。Set拥有与Collection完全相同的接口。一个Set不能保证自己可按任何特定的顺序维持自己的元素

  HashSet* 用于除非常小的以外的所有Set。对象也必须定义hashCode()

  ArraySet 由一个数组后推得到的Set。面向非常小的Set设计,特别是那些需要频繁创建和删除的。对于小Set,与HashSet相比,ArraySet创建和反复所需付出的代价都要小得多。但随着Set的增大,它的性能也会大打折扣。不需要HashCode()

  TreeSet 由一个“红黑树”后推得到的顺序Set。这样一来,我们就可以从一个Set里提到一个顺序集合

  直至本书写作的时候,TreeSet仍然只是宣布,尚未正式实现。所以这里没有提供使用TreeSet的例子。

Set拥有是否与Collection完全相同的接口_Java的对象_Java程序_课课家

  下面这个例子并没有列出用一个Set能够做的全部事情,因为接口与Collection是相同的,前例已经练习过了。相反,我们要例示的重点在于使一个Set独一无二的行为:

  //: Set1.java

  // Things you can do with Sets

  package c08.newcollections;

  import java.util.*;

  public class Set1 {

  public static void testVisual(Set a) {

  Collection1.fill(a);

  Collection1.fill(a);

  Collection1.fill(a);

  Collection1.print(a); // No duplicates!

  // Add another set to this one:

  a.addAll(a);

  a.add("one");

  a.add("one");

  a.add("one");

  Collection1.print(a);

  // Look something up:

  System.out.println("a.contains(\\"one\\"): " +

  a.contains("one"));

  }

  public static void main(String[] args) {

  testVisual(new HashSet());

  testVisual(new TreeSet());

  }

  } ///:~

  重复的值被添加到Set,但在打印的时候,我们会发现Set只接受每个值的一个实例。

  运行这个程序时,会注意到由HashSet维持的顺序与ArraySet是不同的。这是由于它们采用了不同的方法来保存元素,以便它们以后的定位。ArraySet保持着它们的顺序状态,而HashSet使用一个散列函数,这是特别为快速检索设计的)。创建自己的类型时,一定要注意Set需要通过一种方式来维持一种存储顺序,就象本章早些时候展示的“groundhog”(土拔鼠)例子那样。下面是一个例子:

  //: Set2.java

  // Putting your own type in a Set

  package c08.newcollections;

  import java.util.*;

  class MyType implements Comparable {

  private int i;

  public MyType(int n) { i = n; }

  public boolean equals(Object o) {

  return

  (o instanceof MyType)

  && (i == ((MyType)o).i);

  }

  public int hashCode() { return i; }

  public String toString() { return i + " "; }

  public int compareTo(Object o) {

  int i2 = ((MyType) o).i;

  return (i2 < i -1 : (i2 == i 0 : 1));

  }

  }

  public class Set2 {

  public static Set fill(Set a, int size) {

  for(int i = 0; i < size; i++)

  a.add(new MyType(i));

  return a;

  }

  public static Set fill(Set a) {

  return fill(a, 10);

  }

  public static void test(Set a) {

  fill(a);

  fill(a); // Try to add duplicates

  fill(a);

  a.addAll(fill(new TreeSet()));

  System.out.println(a);

  }

  public static void main(String[] args) {

  test(new HashSet());

  test(new TreeSet());

  }

  } ///:~

  对equals()及hashCode()的定义遵照“groundhog”例子已经给出的形式。在两种情况下都必须定义一个equals()。但只有要把类置入一个HashSet的前提下,才有必要使用hashCode()——这种情况是完全有可能的,因为通常应先选择作为一个Set实现。

赞(0)
踩(0)
分享到:
华为认证网络工程师 HCIE直播课视频教程