posts - 6,  comments - 3,  trackbacks - 0

Collections 的排序【转】- -

                                      

 在使用 Java Collections Framework 时,必须知道 Collections 类中的变量是哪些。这个类包含大量支持集合操作的静态方法。在这里,我们不会对所有方法进行介绍,因为您可以自己阅读 API,但是我们将介绍两个经常出现在 Java 代码中的方法:

  • copy()
  • sort()

第一个方法允许将一个集合的内容复制到另一个集合,如下所示:


List source = new ArrayList();
source.add("one");
source.add("two");
List target = new ArrayList();
target.add("three");
target.add("four");

Collections.copy(target, source);
System.out.println(target);

该代码将 source 复制到 target 中。目标代码的大小必须与源代码的大小相同,这样,就无法将 List 复制到空的 List 中。

sort() 方法元素归类成其自然顺序。所有元素都必须实现 Comparable 接口,这样,它们就可以相互比较。像 String 这样的内置类也已经创建。因此,对于一组字符串而言,可以使用以下代码按照字典顺序的升序顺序对字符串进行排序:


List strings = new ArrayList();
strings.add("one");
strings.add("two");
strings.add("three");
strings.add("four");

Collections.sort(strings);
System.out.println(strings);
 

您将在控制台中获得 [four, one, three, two]。但是现在可以对创建的类进行分类吗?可以对 Adult 进行分类。首先要让类进行相互比较:


public class Adult extends Person implements Comparable {
	...
} 

然后要重写 compareTo() 来比较两个 Adult 实例。我们将保持我们的例子在比较方面的简单性,所以该例不会进行太多的比较操作:


public int compareTo(Object other) {
	final int LESS_THAN = -1;
	final int EQUAL = 0;
	final int GREATER_THAN = 1;

	Adult otherAdult = (Adult) other;
	if ( this == otherAdult ) return EQUAL;

	int comparison = this.firstname.compareTo(otherAdult.firstname);
	if (comparison != EQUAL) return comparison;
	
	comparison = this.lastname.compareTo(otherAdult.lastname);
	if (comparison != EQUAL) return comparison;
	
	return EQUAL;
}

任何小于 0 的数字都意味着“小于”,但是 -1 是表示这个意思一个很好用的值。与此类似,用 1 表示“大于”也很方便。正如您可以看到的,0 则意味着“等于”。以这种方式比较两个对象显然是一个手动过程。您必须遍历实例变量并比较每个变量。在这种情况下,我们要比较名和姓,并根据姓氏有效地对人们进行排序。但是您应该能够明白为什么我们的例子过于简单。每个 Adult 都只有一个名和姓。如果想进行深层的比较,那么必须比较每个 AdultWallet,以查看它们是否相等,这可能意味着我们必须在 Wallet 和其余对象上实现 compareTo()。此外,为了正确进行比较,无论何时重写 compareTo(),都必须确保该比较与 equals() 是一致的。我们没有实现 equals(),所以不用担心要与它一致,但我们可以做到这一点。事实上,在返回 EQUAL 之前,我已经看到包含类似以下代码行的代码:


assert this.equals(otherAdult) : "compareTo inconsistent with equals.";

比较对象的其他方法是:提取 compareTo() 中的算法,将其放入 Comparator 类型的对象中,然后对将分类的集合调用 Collections.sort()Comparator,如下所示:


public class AdultComparator implements Comparator {

	public int compare(Object object1, Object object2) {
		final int LESS_THAN = -1;
		final int EQUAL = 0;
		final int GREATER_THAN = 1;

		if ((object1 == null) ;amp;amp (object2 == null))
			return EQUAL;
		if (object1 == null)
			return LESS_THAN;
		if (object2 == null)
			return GREATER_THAN;

		Adult adult1 = (Adult) object1;
		Adult adult2 = (Adult) object2;
		if (adult1 == adult2)
			return EQUAL;

		int comparison = adult1.firstname.compareTo(adult2.firstname);
		if (comparison != EQUAL)
			return comparison;

		comparison = adult1.lastname.compareTo(adult2.lastname);
		if (comparison != EQUAL)
			return comparison;

		return EQUAL;
	}
}

public class CommunityApplication {

	public static void main(String[] args) {
		Adult adult1 = new Adult();
		adult1.setFirstname("Bob");
		adult1.setLastname("Smith");
		
		Adult adult2 = new Adult();
		adult2.setFirstname("Al");
		adult2.setLastname("Jones");
		
		List adults = new ArrayList();
		adults.add(adult1);
		adults.add(adult2);
		
		Collections.sort(adults, new AdultComparator());
		System.out.println(adults);
	}
} 

在控制台窗口中,应该看到以某种顺序排列的“Al Jones”和“Bob Smith”。

使用第二种方法是有一些好的理由的。技术方面的理由已经超出了本文的讨论范围。不过,从好的 OOD 的角度来看,将比较代码隔离到另一个对象中,而不是为每个 Adult 提供将自身与其他对象比较的能力是一个好主意。然而,因为这正是 equals() 要做的事,所以即使结果是布尔值,对于每种方法而言,那些仍然是一些好参数。

使用集合


何时应该使用特殊类型的集合?这是一个由您做出的判断决定,而且,正是因为这类的决定,您希望像一位编程人员那样付出很多。

尽管许多专业人士相信,没有太多关于在任一给定情况下使用哪些类的硬性规定。以我的个人经验而论,大多数时间里,我使用集合、ArrayListHashMap(请记住,Map 不是真正的集合)获得了成功。您自己去体验可能也会有同样的效果。以下是一些经验法则,其中的一些显然要好于另外一些:

  • 在认为自己需要一个集合时,从使用 List 开始,然后让代码告诉您是否需要另一种类型的集合。
  • 如果需要惟一的一组什么东西,那么请使用 Set
  • 在遍历集合时,如果迭代顺序很重要,则使用可用的 Tree... 风格的集合。
  • 避免使用 Vector,除非需要利用其同步功能。
  • 直到(除非)性能出现问题,否则不用担心最优化。

集合是 Java 语言的最强大的一个方面。不要害怕使用集合,但要提防“转向”。例如,以下是一个从 Array 转换到 ArrayList 的一个便利方法:


Adult adult1 = new Adult();
Adult adult2 = new Adult();
Adult adult3 = new Adult();
		
List immutableList = Arrays.asList(new Object[] { adult1, adult2, adult3 });
theList.add(new Adult());

这个代码抛出一个 UnsupportedOperationException,因为由 Arrays.asList() 返回的 List 是不可变的。而您又无法将新的元素添加到不可变的 List 中,所以必须留心一点。

posted on 2005-11-30 12:00 Java&Inter 阅读(689) 评论(0)  编辑  收藏 所属分类: Java技术

只有注册用户登录后才能发表评论。


网站导航:
 

<2024年11月>
272829303112
3456789
10111213141516
17181920212223
24252627282930
1234567

常用链接

留言簿(1)

随笔分类(3)

随笔档案(6)

文章分类(24)

文章档案(22)

收藏夹(2)

经常去的Blog

  • Eclipse/GEF
  • 关于Eclipse插件(plugins)开发的心得,主要包括:SWT/JFACE/GEF/EMF/RCP

搜索

  •  

最新评论

阅读排行榜

评论排行榜