java part part,java泛型指导手册(part1),指导手册part1

java泛型指导手册(part1),指导手册part1

index

1.大致了解一下

从java5开始,泛型就被加入了java。泛型的意义在于:在你操作object之前,提供了一种指定特定类型为更加通用目的的类或方法的手段。听起来很抽象吧?来点例子看看。

注:泛型当然可以用在不是collection的其他类上,但是呢,用collection来展示泛型的基本概念是很好的。

泛型的例子

List这个接口代表一列表object实例,这意味着我们可以在List里放任何Object,比如:

List list = new ArrayList();

list.add(new Integer(2));

list.add("a String");

因为任何object都可能被加入进来,所以你不得不进行类型转换。比如:

Integer integer = (Integer) list.get(0);

String string = (String) list.get(1);

很经常的一个情况是,你在一个List里仅添加一种类型数据进去,比如String或其他东西,而不是像我在上面做的一样,把integer和String混在一起。

于是,你使用泛型这一特性,可以限制放在List里的object。除此之外,你省去了类型转换的烦恼。看一下用泛型的真正例子:

List strings = new ArrayList();

strings.add("a String");

String aString = strings.get(0);

牛逼吧?

java7里的类型猜测

泛型特性在java7里做了升级。从7开始,java编译器可以从你赋值给的那个变量的信息知道collection的类型,这里是java7里的泛型例子:

List strings = new ArrayList<>();

注意看,ArrayList的泛型类型已经被省略了,仅有<>留了下来。有时候,这东西也叫做菱形操作符。当你写一个菱形操作符作为一个泛型类型,java的编译器会假设这个被初始化的类和它赋值给的那个变量(i.e.左边的变量)有相同的类型。在上面的例子,String就是泛型的类型,应为List变量把String设置为了它的类型。

循环里的泛型

java5有一个新的for循环,叫做for-each, 这东西对于制定泛型的collection处理的很好。来个例子:

List strings = new ArrayList();

//... add String instances to the strings list...

for(String aString : strings){

System.out.println(aString);

}

这个for-each循环迭代在strings列表里的所有String实例。

每次迭代,下一个String实例就赋值给aString变量。这个for-loop循环比原来的while循环更加精小,在while里你不得不迭代地使用collection的迭代器(Iterator)的Iterator.next()方法去获得下个实例,这导致代码臃肿。

泛型之于非collection的其他类型

你当然可以将泛型用于其他class,而非仅仅是collection。你可以将你自己的class泛型化。这个以后再说细节。

2. java中的泛型List(Generic List in Java)

java的List接口(java.util.List)能够被泛型化。这就是说,List的一个实例能够被给定一个类型,所以只有那种类型的实例能插入List中和从List中被读取,这里就是一个例子:

List list = new ArrayList;

这个list现在仅仅和String类型的实例联系,这意味着你只能把String放进这个list。不要放别的进list,编译器会抱怨。

泛型的类型检查,仅仅在编译期检查。在运行时你可以调整代码,使字符串列表具有字符串插入的其他对象。不过这是个坏主意。(At runtime it is possible to tweak your code so that a String List has other objects that String’s inserted. This is a bad idea, though.)

进入一个泛型的列表

如下,你能get和insert泛型list的元素:

List list = new ArrayList;

String string1 = "a string";

list.add(string1);

String string2 = list.get(0);

注意,没必要对List.get()方法中得到的对象进行转型,虽然平常需要。

编译器已经知道这个List只包含String的实例,所以转型(cast)是没有必要的。

在泛型化的列表中的迭代

你可以使用迭代器迭代泛型列表,如下所示:

List list = new ArrayList;

Iterator iterator = list.iterator();

while(iterator.hasNext()){

String aString = iterator.next();

}

跟上面的进入一个泛型的列表里一样,不必转型,在while的跌代器里,你也不必转型。

你也可以使用新的for-loop,如下:

List list = new ArrayList;

for(String aString : list) {

System.out.println(aString);

}

注意,现在有一个String对象,aString,在for-loop的括号里被声明。

每一次的迭代,这个aString都获得了list的当前元素。

3. Java中的泛型集合(Generic Set in Java)

Java的Set接口(java.util.Set)可以被泛型化。也就是说,Set的实例能够被给定一个类型,所以仅有那种类型的实例能在Set中插入,读取。例子如下:

Set set = new HashSet;

这个集合现在仅仅与String类型联系起来了,意味着,只有String类型的实例能够放入这个set里,不要放别的进set,编译器会抱怨。

泛型的类型检查,仅仅在编译期检查。在运行时你可以调整代码,使字符串集合(Set)具有字符串插入的其他对象。不过这是个坏主意。(At runtime it is possible to tweak your code so that a String Set has other objects that String’s inserted. This is a bad idea, though.)

为泛型化的集合添加元素

通常使用add(),一如你平常也常用的

Set set = new HashSet;

String string1 = "a string";

set.add(string1);

那么最大的差别是什么呢?好吧,就是你尝试添加非String的实例进入上述Set,编译器会抱怨。这是个很好的额外的类型检查特性,你值得拥有。

迭代一个泛型化的Set

使用一个iterator(迭代器)吧,如下:

Set set = new HashSet;

Iterator iterator = set.iterator();

while(iterator.hasNext()){

String aString = iterator.next();

}

请注意,就像之前在List那一节所说一样,不必为interator.next()去转型。

因为Set已经被泛型化了(泛型化的意思是有了一个指定的type),编译器知道为你打理一切,不论你使用iterator还是for-loop.

下面就为你展示使用for-loop:

Set set = new HashSet;

for(String aString : set) {

System.out.println(aString);

}

4. java中的泛型Map(Generic Map in Java)

Map这个接口(java.util.Map)也是能够被泛型化的,这就是说,在一个泛型化的Map中,你可以指定为key-value指定特定的类型,这里是例子:

Map set = new HashMap;

这个Map实例set,现在只能接受Integer作为keys,接受String作为values

一样地,泛型的类型检查仅仅发生在编译期。你可以在运行期调整你的代码,这样你的其他实例就能插入了(我翻译时这段话总是不太确定,是能够动态改变key-value对应的原来的Integer-String类型吗?)。尽管这是一个坏主意。

进入(读取)一个泛型化的Map

添加和获得一个泛型化的Map的元素,一如往常,你可以使用put(),get()

Map map = new HashMap;

Integer key1 = new Integer(123);

String value1 = "value 1";

map.put(key1, value1);

String value1_1 = map.get(key1);

所以大的改变在哪呢?(作者应该是在将新的java7特性羞辱旧版java4,我说可能啊)。

在于一个很nice的类型检查:对于上诉例子,当你的key-value对不是Integer-String时,编译器会抱怨。

java5的auto boxing特性能给我们带来很大方便(使得我们的代码叙述更加人性化):

Map map = new HashMap;

Integer key1 = 123;

String value1 = "value 1";

map.put(key1, value1);

//or

map.put(123, value1);

String value1_1 = map.get(123);

迭代一个泛型化的Map

一个Map,有两个collection可以被迭代: key Set 和 value Set。

通常情况下,你迭代key Set,然后通过Map.get(key)来获取value。

来,给你两个例子:

Map map = new HashMap;

//... add key, value pairs to the Map

// iterate keys.

Iterator keyIterator = map.keySet().iterator();

while(keyIterator.hasNext()){

Integer aKey = keyIterator.next();

String aValue = map.get(aKey);

}

Iterator valueIterator = map.values().iterator();

while(valueIterator.hasNext()){

String aString = valueIterator.next();

}

第二个例子

Map map = new HashMap;

//... add key, value pairs to the Map

for(Integer aKey : map.keySet()) {

String aValue = map.get(aKey);

System.out.println("" + aKey + ":" + aValue);

}

for(String aValue : map.values()) {

System.out.println(aValue);

}

同理,不必进行类型检查,编译器知道key的类型一定是Integer,value的值一定是String.

5.java的泛型化类

相关文章暂无相关文章

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值