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

中国优秀的程序员网站程序员频道CXYCLUB技术地图
热搜:
更多>>
 
您所在的位置: 程序员俱乐部 > 编程开发 > JAVA > Java程序员从笨鸟到菜鸟之(四)java开发常用类(包装,数字处理集合等)(上)

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

 2012/4/18 2:31:07  qcyycom  程序员俱乐部  我要评论(0)
  • 摘要:一:首谈java中的包装类Java为基本类型提供包装类,这使得任何接受对象的操作也可以用来操作基本类型,直接将简单类型的变量表示为一个类,在执行变量类型的相互转换时,我们会大量使用这些包装类。java是一种面向对象语言,java中的类把方法与数据连接在一起,并构成了自包含式的处理单元.但在java中不能定义基本类型(primitivetype),为了能将基本类型视为对象来处理,并能连接相关的方法,java为每个基本类型都提供了包装类,这样,我们便可以把这些基本类型转化为对象来处理了
  • 标签:程序 程序员 常用 Java 开发

一:首谈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)?单元素添加、caozuo.html" target="_blank">删除操作:

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):?
查找集合中是否含有集合c?中所有元素

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

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

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

void?retainAll(Collection?c)?:?
从集合中删除集合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对象存储空间。

发表评论
用户名: 匿名