`

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

阅读更多

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

一:首谈java中的包装类

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

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

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

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

(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会自动创建一个对象。例如:Integeri=100;//没有通过使用new来显示建立,java自动完成。

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

·inti=11;

·Integerj=i;//自动装箱

·intk=j//自动拆箱

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

publicstaticvoidmain(String[]args){

Integera=100;

Integerb=100;

Integerc=200;

Integerd=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在编译的时候Integera=100;被翻译成->Integera=Integer.valueOf(100);
关键就在于这个
valueOf()的方法。

publicstaticIntegervalueOf(inti){

finalintoffset=128;

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

returnIntegerCache.cache[i+offset];

}

returnnewInteger(i);

}

privatestaticclassIntegerCache{

privateIntegerCache(){}

staticfinalIntegercache[]=newInteger[-(-128)+127+1];

static{

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

cache=newInteger(i-128);

}

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

staticfinalIntegercache[]=newInteger[-(-128)+127+1];//cache[]变成静态

static{

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

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

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

。那么当我们Integerb=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)单元素添加、删除操作:

booleanadd(Objecto):
将对象添加给集合

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

(2)
查询操作:

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

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

booleancontains(Objecto)
:查找集合中是否含有对象o

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

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

booleancontainsAll(Collectionc):
查找集合中是否含有集合c中所有元素

booleanaddAll(Collectionc):
将集合c中所有元素添加给该集合

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

voidremoveAll(Collectionc):
从集合中删除集合c中的所有元素

voidretainAll(Collectionc):
从集合中删除集合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中搜索元素可以从列表的头部或尾部开始,如果找到元素,还将报告元素所在的位置:

voidadd(intindex,Objectelement):
在指定位置index上添加元素element

booleanaddAll(intindex,Collectionc):
将集合c的所有元素添加到指定位置index

Objectget(intindex):
返回List中指定位置的元素

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

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

Objectremove(intindex)
 :删除指定位置上的元素

Objectset(intindex,Objectelement)
:用元素element取代位置index上的元素,并且返回旧的元素

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

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

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

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

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

LinkedList


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

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



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

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics