Java程序员从笨鸟到菜鸟之(四)java开发常用类(包装,数字处理集合等)(上)

 本文来自:曹胜欢博客专栏。转载请注明出处:http://blog.csdn.net/csh624366188

 

一:首谈java中的包装类

     Java为基本类型提供包装类,这使得任何接受对象的操作也可以用来操作基本类型,直接将简单类型的变量表示为一个类,在执行变量类型的相互转换时,我们会大量使用这些包装类。java是一种面向对象语言,java中的类把方法与数据连接在一起,并构成了自包含式的处理单元.但在java中不能定义基本类型(primitive type),为了能将基本类型视为对象来处理,并能连接相关的方法,java为每个基本类型都提供了包装类,这样,我们便可以把这些基本类型转化为对象来处理了.这些包装类有:Boolean,Byte,Short,Character,Integer,Long,Float,Void

值得说明的是,java是可以直接处理基本类型的,但是在有些情况下我们需要将其作为对象来处理,这时就需要将其转化为包装类了.所有的包装类(Wrapper Class)都有共同的方法,他们是:

(1)带有基本值参数并创建包装类对象的构造函数.如可以利用Integer   装类创建对象,Integer obj=new Integer(145);

(2)带有字符串参数并创建包装类对象的构造函数.new Integer("-45.36");

(3)生成字符串表示法的toString()方法,obj.toString().

(4)对同一个类的两个对象进行比较的equals()方法,obj1.eauqls(obj2);

(5)生成哈稀表代码的hashCode方法,obj.hasCode();

(6)将字符串转换为基本值的 parseType方法,Integer.parseInt(args[0]);

(7)可生成对象基本值的typeValue方法,obj.intValue();

在一定的场合,运用java包装类来解决问题,能大大提高编程效率.

包装类的自动装箱,自动拆箱

所谓装箱,就是把基本类型用它们相对应的引用类型包起来,使它们可以具有对象的特质,如我们可以把int型包装成Integer类的对象,或者把double包装成Double,等等。 
所谓拆箱,就是跟装箱的方向相反,将
IntegerDouble这样的引用类型的对象重新简化为值类型的数据 

javaSE5.0后提供了自动装箱与拆箱的功能,此功能事实上是编译器来帮您的忙,编译器在编译时期依您所编写的方法,决定是否进行装箱或拆箱动作。 
自动装箱的过程:每当需要一种类型的对象时,这种基本类型就自动地封装到与它相同类型的包装中。 

自动拆箱的过程:每当需要一个值时,被装箱对象中的值就被自动地提取出来,没必要再去调用
intValue()doubleValue()方法。 
自动装箱,只需将该值赋给一个类型包装器引用,
java会自动创建一个对象。例如:Integer i=100;//没有通过使用new来显示建立,java自动完成。 

自动拆箱,只需将该对象值赋给一个基本类型即可,例如

· int i = 11;  

· Integer j = i; //自动装箱  

· int k = j //自动拆箱 

然而在Integer的自动装拆箱会有些细节值得注意:

public static void main(String[] args) {  

    Integer a=100;  

    Integer b=100;   

    Integer c=200;  

    Integer d=200;   

   System.out.println(a==b);   //1  

   System.out.println(a==100); //2     

  System.out.println(c==d);   //3  

  System.out.println(c==200); //4  

   }  
java种,"=="是比较objectreference而不是value,自动装箱后,abcd都是Integer这个Oject,因此“==”比较的是其引用。按照常规思维,13都应该输出false。但结果是: 
true 
true 
false 
true
结果
24,是因为ac进行了自动拆箱,因此其比较是基本数据类型的比较,就跟int比较时一样的,“==”在这里比较的是它们的值,而不是引用。 
对于结果
1,虽然比较的时候,还是比较对象的reference,但是自动装箱时,java在编译的时候 Integer a = 100; 被翻译成-> Integer a = Integer.valueOf(100); 
关键就在于这个
valueOf()的方法。 

public static Integer valueOf(int i) {     

final int offset = 128;     

if (i >= -128 && i <= 127) { // must cache     

return IntegerCache.cache[i + offset];     

}     

return new Integer(i);     

}     

private static class IntegerCache {     

private IntegerCache(){}     

static final Integer cache[] = new Integer[-(-128) + 127 + 1];     

static {     

for(int i = 0; i < cache.length; i++)     

cache = new Integer(i - 128);     

}     

}   
根据上面的
jdk源码,java为了提高效率,IntegerCache类中有一个数组缓存 了值从-128127Integer对象。当我们调用Integer.valueOfint i)的时候,如果i的值是>=-128<=127时,会直接从这个缓存中返回一个对象,否则就new一个Integer对象。 
具体如下: 

static final Integer cache[] = new Integer[-(-128) + 127 + 1]; //cache[]变成静态  

static {  

        for(int i = 0; i < cache.length; i++)  

        cache[i] = new Integer(i - 128); //初始化cache[i]  

}  
这是用一个
for循环对数组cache赋值,cache[255] = new Integer(255-128),也就是newl一个Integer(127) ,并把引用赋值给cache[255],好了,然后是Integer b= 127,流程基本一样,最后又到了cache[255] = new Integer(255-128),这一句,那我们迷糊了,这不是又new了一个对象127吗,然后把引用赋值给cache[255],我们比较这两个引 用(前面声明a的时候也有一个),由于是不同的地址,所以肯定不会相等,应该返回false啊!呵呵,这么想你就错了,请注意看for语句给 cache[i]初始化的时候外面还一个{}呢,{}前面一个大大的static关键字,是静态的,那么我们就可以回想下static有什么特性了,只能 初始化一次,在对象间共享,也就是不同的对象共享同一个static数据

。那么当我们Integer b = 127的时候,并没有new出一个新对象来,而是共享了a这个对象的引用,记住,他们共享了同一个引用!!!,那么我们进行比较a==b时,由于是同一个对象的引用(她们在堆中的地址相同),那当然返回true了!!! 

二:进军集合类

集合其实就是存放对象的容器,专业点说就是集合是用来存储和管理其他对象的对象,即对象的容器。集合可以扩容,长度可变,可以存储多种类型的数据,而数组长度不可变,只能存储单一类型的元素

用一张图来总结一下集合的总况:


下面是网上找的一个图片:


集合中的结构和几个实现类:


总述:ListSetMap是这个集合体系中最主要的三个接口。
其中
ListSet继承自Collection接口。
Set
不允许元素重复。HashSetTreeSet是两个主要的实现类。
List
有序且允许元素重复。ArrayListLinkedListVector是三个主要的实现类。
   Map
也属于集合系统,但和Collection接口不同。Mapkeyvalue的映射集合,其中key列就是一个集合。key不能重复,但是value可以重复。HashMapTreeMapHashtable是三个主要的实现类。
   SortedSet
SortedMap接口对元素按指定规则排序,SortedMap是对key列进行排序。

具体来说:

1.Collection 接口用于表示任何对象或元素组。想要尽可能以常规方式处理一组元素时,就使用这一接口。

操作:

(1) 单元素添加、删除操作:

boolean add(Object o):
将对象添加给集合

boolean remove(Object o): 
如果集合中有与o相匹配的对象,则删除对象o

(2) 
查询操作:

int size() 
:返回当前集合中元素的数量

boolean isEmpty() 
:判断集合中是否有任何元素

boolean contains(Object o) 
:查找集合中是否含有对象o

Iterator iterator() 
:返回一个迭代器,用来访问集合中的各个元素

(3) 
组操作 :作用于元素组或整个集合

boolean containsAll(Collection c): 
查找集合中是否含有集合中所有元素

boolean addAll(Collection c) : 
将集合中所有元素添加给该集合

void clear(): 
删除集合中所有元素

void removeAll(Collection c) : 
从集合中删除集合中的所有元素

void retainAll(Collection c) : 
从集合中删除集合中不包含的元素

(4) Collection
转换为Object数组 :

Object[] toArray() 
:返回一个内含集合所有元素的array

Object[] toArray(Object[] a) 
:返回一个内含集合所有元素的array。运行期返回的array和参数a的型别相同,需要转换为正确型别。

此外,您还可以把集合转换成其它任何其它的对象数组。但是,您不能直接把集合转换成基本数据类型的数组,因为集合必须持有对象。

斜体接口方法是可选的。因为一个接口实现必须实现所有接口方法,调用程序就需要一种途径来知道一个可选的方法是不是不受支持。如果调用一种可选方法 时,一个 UnsupportedOperationException 被抛出,则操作失败,因为方法不受支持。此异常类继承 RuntimeException 类,避免了将所有集合操作放入 try-catch 块。

Collection
不提供get()方法。如果要遍历Collectin中的元素,就必须用Iterator

2.List接口Collection进行了简单的扩充,它的具体实现类常用的有ArrayListLinkedList。你可以将任何东西放到一个 List容器中,并在需要时从中取出。ArrayList从其命名中可以看出它是一种类似数组的形式进行存储,因此它的随机访问速度极快,而 LinkedList的内部实现是链表,它适合于在链表中间需要频繁进行插入和删除操作。在具体应用时可以根据需要自由选择。前面说的Iterator只 能对容器进行向前遍历,而ListIterator则继承了Iterator的思想,并提供了对List进行双向遍历的方法。

(1) 面向位置的操作包括插入某个元素或 Collection 的功能,还包括获取、除去或更改元素的功能。在 List 中搜索元素可以从列表的头部或尾部开始,如果找到元素,还将报告元素所在的位置 :

void add(int index, Object element): 
在指定位置index上添加元素element

boolean addAll(int index, Collection c): 
将集合c的所有元素添加到指定位置index

Object get(int index): 
返回List中指定位置的元素

int indexOf(Object o): 
返回第一个出现元素o的位置,否则返回-1

int lastIndexOf(Object o) 
:返回最后一个出现元素o的位置,否则返回-1

Object remove(int index)
 :删除指定位置上的元素

Object set(int index, Object element) 
:用元素element取代位置index上的元素,并且返回旧的元素

(2) List 
接口不但以位置序列迭代的遍历整个列表,还能处理集合的子集:

ListIterator listIterator() : 
返回一个列表迭代器,用来访问列表中的元素

ListIterator listIterator(int index) : 
返回一个列表迭代器,用来从指定位置index开始访问列表中的元素

List subList(int fromIndex, int toIndex) 
:返回从指定位置fromIndex(包含)到toIndex(不包含)范围中各个元素的列表视图

对子列表的更改(如 add()remove() 和 set() 调用)对底层 List 也有影响。” “ArrayList 和 LinkedList 都实现 Cloneable 接口,都提供了两个构造函数,一个无参的,一个接受另一个Collection”

LinkedList


LinkedList
类添加了一些处理列表两端元素的方法。
(1) void addFirst(Object o): 
将对象o添加到列表的开头
void addLast(Object o)
:将对象o添加到列表的结尾
(2) Object getFirst(): 
返回列表开头的元素
Object getLast(): 
返回列表结尾的元素
(3) Object removeFirst(): 
删除并且返回列表开头的元素
Object removeLast():
删除并且返回列表结尾的元素
(4) LinkedList(): 
构建一个空的链接列表
LinkedList(Collection c): 
构建一个链接列表,并且添加集合c的所有元素
使用这些新方法,您就可以轻松的把 LinkedList 当作一个堆栈、队列或其它面向端点的数据结构。
ArrayList

ArrayList
类封装了一个动态再分配的Object[]数组。每个ArrayList对象有一个capacity。这个capacity表示存储列表中元素的数组的容量。当元素添加到ArrayList时,它的capacity在常量时间内自动增加。
 在向一个
ArrayList对象添加大量元素的程序中,可使用ensureCapacity方法增加capacity。这可以减少增加重分配的数量。
 (1) void ensureCapacity(int minCapacity): 
ArrayList对象容量增加minCapacity
(2) void trimToSize(): 
整理ArrayList对象容量为列表当前大小。程序可使用这个操作减少ArrayList对象存储空间。



 本文来自:曹胜欢博客专栏。转载请注明出处:http://blog.csdn.net/csh624366188

posted @ 2012-02-24 10:29  javait03  阅读(243)  评论(0编辑  收藏  举报