Java中的集合(一):泛型

在JavaSE 1.5中,Java引入泛型的概念。那么何为泛型呢?
  泛型就是将类型参数化,也就是说将所操作的数据类型指定为一个参数,从而使代码可以复用,并且引入泛型意味着更好的类型安全。
  泛型可以被使用到类、接口和方法中。
  泛型的使用在集合中尤为突出。

一、定义&使用

在定义泛型类、泛型接口或泛型方法使,在<>中指定一个或多个类型参数的名字。对于类型参数的名字可以使用任何Java标识符(由字符、数字、下划线(_)、美元符($)组成,不能以数字开头),但为了规范化和达到见名知意的目的,建议使用简练的名字,多使用单个字符,并且最好避免小写字母。
  在这里建议大家多看看Java API的源码,并不一定要看懂程序,而是看那些大牛的编码风格,命名风格,很值得去学习一下。
比如在API中的类型参数名字:E (Element)元素
             K (Key)键
             V (Value) 值
就像这样

//泛型接口
public interface Test<E>{}

//单个类型参数的泛型类
public class Test1<E> {
   public void test(E e){}
}

//多个类型参数的泛型类
public class Test2<K,V>{}

二、泛型方法

泛型接口和泛型类在声明上相对简单些,看上面的例子就可以了,对于泛型方法,我们看API中的一个例子,在java.util.Collections有一个对集合按照某种规则进行排序的方法sort(),方法如下:

public static <T extends Comparable<? super T>> void sort(List<T> list){//...}

泛型方法的声明需要在返回值前面进行泛型的生命,和泛型类和泛型接口一样,可以声明多个泛型,用英文逗号隔开。
  泛型方法使我们可以使用未定义在类声明中的类型参数。

三、规则&限制

1.泛型的类型参数只能是类类型,不能是简单类型。
List<int> list = new ArrayList<int>();
/*这样写也是错误,是自己粗心大意,有些想当然了。如果由于自己的失误给大家带来
   误解,在这里向大家表示歉意。
*/
2.泛型的类型参数可以使用extends语句,例如:
public class Test<T extends List> {//...}

在以上的类声明中类型参数只能是List的子类,不能为其他类类型 。请注意,在这里extends关键字不能理解成继承的意思,因为在这里extends既适用于类也适用于接口,就如上面那样,所以在这里extends应该理解为“是一个”的意思。

3.泛型的类型参数可以有多个,就像API中的Map一样,
public interface Map<K,V>{//...}
4.同一种泛型对应多个版本,因为参数类型是不确定的,但是不同版本的泛型类实例是不兼容的,包括具有继承关系的类类型。下面看下面这个例子。
public class Test{
  public static void test(List<Animal> list){}
  static class Animal{}
  static class Dog extends Animal{}
  static class Cat extends Animal{}
  public static void main(String[] args){
    //创建Animal类型的集合
    List<Animal> animalList = new ArrayList<Animal>();
    animalList.add(new Animal());
    //由于Dog和Cat类继承自Animal,所以也可以说Dog和Cat也是Animal类型的,所以可以网Animal类型的集合中添加Dog和Cat的实例
    animalList.add(new Dog());
    animalList.add(new Cat());
    //创建Dog类型的集合
    List<Dog> dogList = new ArrayList<Dog>();
    dogList.add(new Dog());
    dogList.add(new Dog());
    //调用test方法
    test(animalList);
    test(dogList);//编译器将会报错
    }
}

在上面的实例中我们首先定义了一个接收Animal类型集合作为参数的test方法,然后再Main主方法中分别定义了Animal类型和Dog类型的List集合。
接下来我们调用test方法将animalListdogList作为参数传进去,
这时我们会发现test(dogList)会报错。
  这是因为将子类集合加入到具有声明为父类集合的参数的方法中是不合法的操作,也就是我们上面说的不同版本的泛型类实例是不兼容的。
  那么你可能要疑问:那么我该怎样使用多态化集合参数呢?
  方法1.使用通配符类型?,就像下面这样

...
public static void test(List<?> list){}
...
public static void main(String[] args){
  ...
  test(animalList);
  test(dogList);//这样编译器就不会报错了
}

方法2.在声明泛型时使用extends语句

...
public static <T extends Animal> void test(List<T> list){}
...
public static void main(String[] args){
  ...
  test(animalList);
  test(dogList);//这样编译器就不会报错了
}

<b>注意</b>:使用上面两种方式时,编译器会组织任何可能破坏形式参数所指集合的行为,也就是不能在定义的方法中,不能向作为参数的集合中添加任何元素,但可以删除元素。

三、其他

数组也是我们经常使用的用来存储数据的一种集合
  对于数组的类型是在运行时期检查的,对于集合的类型检查只会发生在编译时期。
  所以因为多态的关系,将子类数组传入具有声明为父类数组的参数的方法中是完全合法的操作。但是如果将子类数组传入到方法中后,对该数组随意进行赋值操作,会报ArrayStoreException异常,就行下面这样。

public class Test {
  public static void test2(Animal[] animals){
    animals[0] = new Cat();
    animals[1] = new Animal();
  }
  public static void main(String[] args){
    Animal[] animals = new Animal[3];
    Dog[] dogs = new Dog[3];
    test2(animals);
    test2(dogs);
  }
}

test2()方法中对参数数组进行了赋值操作,当将Dog类型的数组传入test2()方法中,在程序运行时会有ArrayStoreException异常。
  因为经验尚浅,所以如果有错误的或者描述不妥的地方,希望各位读者帮忙指正。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,053评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,527评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,779评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,685评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,699评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,609评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,989评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,654评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,890评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,634评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,716评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,394评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,976评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,950评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,191评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,849评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,458评论 2 342

推荐阅读更多精彩内容