Flyingis

Talking and thinking freely !
Flying in the world of GIS !
随笔 - 156, 文章 - 16, 评论 - 589, 引用 - 0
数据加载中……

Java容器分析--数组

         作者:Flyingis

    数组是
Java语言内置的类型,除此之外,Java有多种保存对象引用的方式。Java类库提供了一套相当完整的容器类,使用这些类的方法可以保存和操纵对象。下面分别进行讨论,在研究Java容器类之前,先了解一下Java数组的基本功能和特性。

1.  数组的基本特性

         数组与其它种类的容器(List/Set/Map)之间的区别在于效率、确定的类型和保存基本类型数据的能力。数组是一种高效的存储和随机访问对象引用序列的方式,使用数组可以快速的访问数组中的元素。但是当创建一个数组对象(注意和对象数组的区别)后,数组的大小也就固定了,当数组空间不足的时候就再创建一个新的数组,把旧的数组中所有的引用复制到新的数组中。

         Java中的数组和容器都需要进行边界检查,如果越界就会得到一个RuntimeException异常。这点和C++中有所不同,C++vector的操作符[]不会做边界检查,这在速度上会有一定的提高,Java的数组和容器会因为时刻存在的边界检查带来一些性能上的开销。

         Java中通用的容器类不会以具体的类型来处理对象,容器中的对象都是以Object类型处理的,这是Java中所有类的基类。另外,数组可以保存基本类型,而容器不能,它只能保存任意的Java对象。

         一般情况下,考虑到效率与类型检查,应该尽可能考虑使用数组。如果要解决一般化的问题,数组可能会受到一些限制,这时可以使用Java提供的容器类。 

2.  操作数组的实用功能

         java.util.Arrays类中,有许多static静态方法,提供了操作数组的一些基本功能:

         equals()方法----用于比较两个数组是否相等,相等的条件是两个数组的元素个数必须相等,并且对应位置的元素也相等。

         fill()方法----用以某个值填充整个数组,这个方法有点笨。

         asList()方法----接受任意的数组为参数,将其转变为List容器。

         binarySearch()方法----用于在已经排序的数组中查找元素,需要注意的是必须是已经排序过的数组。当Arrays.binarySearch()找到了查找目标时,该方法将返回一个等于或大于0的值,否则将返回一个负值,表示在该数组目前的排序状态下此目标元素所应该插入的位置。负值的计算公式是“-x-1”x指的是第一个大于查找对象的元素在数组中的位置,如果数组中所有的元素都小于要查找的对象,则x = a.size()。如果数组中包含重复的元素,则无法保证找到的是哪一个元素,如果需要对没有重复元素的数组排序,可以使用TreeSet或者LinkedHashSet。另外,如果使用Comparator排序了某个对象数组,在使用该方法时必须提供同样的Comparator类型的参数。需要注意的是,基本类型数组无法使用Comparator进行排序。

         sort()方法----对数组进行升序排序。

         Java标准类库中,另有static方法System.arraycopy()用来复制数组,它针对所有类型做了重载。

3.  数组的排序

         Java1.01.1两个版本中,类库缺少基本的算法操作,包括排序的操作,Java2对此进行了改善。在进行排序的操作时,需要根据对象的实际类型执行比较操作,如果为每种不同的类型各自编写一个不同的排序方法,将会使得代码很难被复用。一般的程序设计目标应是“将保持不变的事物与会发改变的事物相分离”。在这里,不变的是通用的排序算法,变化的是各种对象相互比较的方式。

Java有两种方式来实现比较的功能,一种是实现java.lang.Comparable接口,该接口只有一个compareTo()方法,并以一个Object类为参数,如果当前对象小于参数则返回负值,如果相等返回零,如果当前对象大于参数则返回正值。另一种比较方法是采用策略(strategy)设计模式,将会发生变化的代码封装在它自己的类(策略对象)中,再将策略对象交给保持不变的代码中,后者使用此策略实现它的算法。因此,可以为不同的比较方式生成不同的对象,将它们用在同样的排序程序中。在此情况下,通过定义一个实现了Comparator接口的类而创建了一个策略,这个策略类有compare()equals()两个方法,一般情况下实现compare()方法即可。

使用上述两种方法即可对任意基本类型的数组进行排序,也可以对任意的对象数组进行排序。再提示一遍,基本类型数组无法使用Comparator进行排序。

Java标准类库中的排序算法针对排序的类型进行了优化——针对基本类型设计了“快速排序”,针对对象设计的“稳定归并排序”。一般不用担心其性能。

其它相关内容:
Java容器分析--List和Set
Java容器分析--Map

posted on 2005-12-15 20:56 Flyingis 阅读(2878) 评论(3)  编辑  收藏 所属分类: JavaSE

评论

# re: Java容器分析--数组  回复  更多评论   

虽然文章很基本,但是,需要的时候就觉得很有用,asList(),asArray()这些方法方法就非常重要了。
2005-12-16 08:27 | david.turing

# re: Java容器分析--数组  回复  更多评论   

下面是我一个朋友写的代码,你可以参考一下中文排序部分。

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

import org.apache.commons.beanutils.BeanUtils;

public class SortUtils {

public static List sortByProperty(Collection objects,String property,boolean desc){
List result=new ArrayList();
try{
Comparator c=new PropertyComparator(property,desc);
result.addAll(objects);
Collections.sort(result,c);
}catch(Exception e){
result.addAll(objects);
}
return result;
}

public static List sortByProperty(Collection objects,String property){
return sortByProperty(objects,property,false);
}

public static List sortByProperty(Collection objects, String property, String sort){
return sortByProperty(objects,property,"desc".equalsIgnoreCase(sort));
}


public static void main(String[] args) throws Exception{
TestEntity te=new TestEntity();
te.setId(1234234);
te.setName("King");
System.out.println(BeanUtils.getProperty(te,"id"));
}
}

class PropertyComparator implements Comparator{
private boolean desc=false;
private String propertyName;

public PropertyComparator(String propertyName){
this.propertyName=propertyName;
}

public PropertyComparator(String propertyName,boolean desc){
this.propertyName=propertyName;
this.desc=desc;
}

public int compare(Object obj1,Object obj2){
try{
String value1 = BeanUtils.getProperty(obj1,propertyName);
String value2 = BeanUtils.getProperty(obj2,propertyName);
if(value1==null) value1="";
if(value2==null) value2="";
value1=new String(value1.getBytes("GBK"),"ISO-8859-1");
value2=new String(value2.getBytes("GBK"),"ISO-8859-1");
if(desc){
return value2.compareTo(value1);
}else{
return value1.compareTo(value2);
}
}catch(Exception e){
throw new IllegalArgumentException(e);
}
}
}
2005-12-16 08:33 | david.turing

# re: Java容器分析--数组  回复  更多评论   

感谢代码分享。我前面转贴了一篇文章《挖掘Jakarta Commons中隐藏的宝贝》,有兴趣可以看一下。
2005-12-18 14:40 | Flyingis

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


网站导航: