java集合框架--泛型

1.泛型概述

泛型是一种特殊的类型,它把指定类型的工作推迟到客户端代码声明并实例化类或方法的时候进行。也被称为参数化类型,可以把类型当做参数一样传递过来,在传递过来之前并不明确,但是在使用的时候就明确了。

泛型是JDK5以后出现的新特性。

2.泛型出现的原因1

package com;

import java.util.ArrayList;
import java.util.Iterator;

public class GenericDemo {
	public static void main(String[] args) {
		//创建集合对象
		ArrayList list = new ArrayList();
		//添加元素
		list.add("hello");
		list.add("world");
		list.add("java");
		//遍历
		for(Iterator<String> iterator = list.iterator();iterator.hasNext();){
			String str = (String)iterator.next();
			System.out.println(str);
		}

	}

}

hello

world

java

上面的代码是将字符串放进集合中,但是集合的add()方法的参数类型时Object,所以我们可以放任意的引用类型,当然如果你存放的是基本类型,那么Jdk5之后会有自动装箱功能,将基本类型转换成引用类型,千万记住,集合存放的是引用类型,而不是基本类型哦。虽然你可以存放基本类型的数据,但是JDK底层依然会转换成引用数据类型的。如果你不明白的话,可以使用反编译工具,将字节码文件反编译一下就知道了。

package com;

import java.util.ArrayList;
import java.util.Iterator;

public class GenericDemo {
	public static void main(String[] args) {
		//创建集合对象
		ArrayList list = new ArrayList();
		//添加元素
		list.add("hello");
		list.add("world");
		list.add("java");
		list.add(new Integer(100));
		list.add(10);//自动装箱

		//遍历
		for(Iterator<String> iterator = list.iterator();iterator.hasNext();){
			String str = (String)iterator.next();
			System.out.println(str);
		}

	}

}

java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String

at com.GenericDemo.main(GenericDemo.java:18)

报错了,类型转换异常,意思是Integer类型不能转换为String类型。这是运行时异常,意思就是在运行期间才会产生这个异常,这样很不方便。

那么此时,我们回顾一下String类型的数组

String[] str = new String[10];
str[0] = "hello";
str[1] = "world";
str[0] = 12;//这边在编译期间就直接报错,为什么?因为是String类型的数组,
//你竟然存放int类型的数据

同理,那么我们能不能在定义集合的时候就采用这种机制呢?

当然啦,集合也采用的是这样机制,在创建集合对象的时候明确元素的数据类型,这样就不会出现这种问题了。这种技术被称为泛型。

那么此时,我们来看泛型的定义吧,泛型就是一种把类型明确的工作推迟到创建对象或调用方法的时候去明确的特殊类型。反而言之,就是在定义集合类的时候,并不给出具体类型,当你创建集合对象的时候给出具体的类型,用来限定集合类型的所有类型,这样是不是很方便。

但是此处的类型只能是引用类型,不能是基本类型哦,要记住虽然有JDK5的自动装箱和拆箱的功能。但是集合本质上存放的还是引用类型的数据,所以你创建集合对象的时候使用泛型就用引用数据类型哦,因为JDK还没有这么强大,哈哈。

package com;

import java.util.ArrayList;
import java.util.Iterator;
//错误代码
public class GenericDemo {
	public static void main(String[] args) {
		//创建集合对象
		ArrayList<String> list = new ArrayList<String>();
		//添加元素
		list.add("hello");
		list.add("world");
		list.add("java");
		list.add(new Integer(100));//这段代码 在编译期间就直接报错 
		//因为我们声明集合中所有元素必须为String类型,而我们存放的却是其他类型的数据
		list.add(10);//自动装箱//和上面一样

		//遍历
		for(Iterator<String> iterator = list.iterator();iterator.hasNext();){
			String str = (String)iterator.next();
			System.out.println(str);
		}

	}

}

3.泛型的好处

那么此时,我们想一下,既然泛型能限定集合元素的数据类型,那么意味着集合中的所有类型都是一样的哦,那么我们我们将字符串取出来的时候,能不能省略类型转换呢?想一下,String类型的数组,当你迭代遍历的时候考虑过类型转换吗?NO,因为我知道此时数组里存放的都是String类型的数据,我当然无须考虑,那么泛型的好处也就来了,就是省去了类型转换的麻烦。

原来的代码

package com;

import java.util.ArrayList;
import java.util.Iterator;

public class GenericDemo {
	public static void main(String[] args) {
		//创建集合对象
		ArrayList<String> list = new ArrayList<String>();
		//添加元素
		list.add("hello");
		list.add("world");
		list.add("java");

		//遍历
		for(Iterator<String> iterator = list.iterator();iterator.hasNext();){
			String str = (String)iterator.next();//类型转换
			System.out.println(str);
		}

	}

}

既然知道,泛型省去了类型转换,那么我们此时将强制类型转换的标记去到如何?

package com;

import java.util.ArrayList;
import java.util.Iterator;

public class GenericDemo {
	public static void main(String[] args) {
		//创建集合对象
		ArrayList<String> list = new ArrayList<String>();
		//添加元素
		list.add("hello");
		list.add("world");
		list.add("java");

		//遍历
		for(Iterator<String> iterator = list.iterator();iterator.hasNext();){
			String str = iterator.next();//类型转换
			System.out.println(str);
		}

	}

}

当然可以啦,因为我在用迭代器的时候就限定了迭代器中的泛型为String类型了,这样后面再取集合中的元素的时候就不用类型转换了,是不是很方便啊,这样的功能太棒了。真的是难为了JDK4之前的程序员,要进行类型转换。

总结一下泛型的好处:

1.提高了程序的安全性

2.将运行期间遇到的问题转移到了编译期间

3.省去了强制类型转换的麻烦

4.泛型在那些地方使用呢?

查看API,如果类、接口、抽象类后面跟的是<E>这样的标记,就意味着要使用泛型了。一般来说就是在集合中使用。

package com;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.ListIterator;

public class ArrayListDemo {
	public static void main(String[] args) {
		//创建ArrayList对象
		ArrayList<String> list = new ArrayList<String>();

		//添加元素
		list.add("哈哈");
		list.add("呵呵");
		list.add("嘻嘻");
		list.add("笨笨");

		//遍历方式一 将ArrayList集合装换为Object[]
		Object[] obj = list.toArray();
		for (int i = 0; i < obj.length; i++) {
			String str = (String) obj[i];
			System.out.println(str);
		}

		System.out.println("----------------------");

		//遍历方式二 使用Iterator迭代器
		for(Iterator<String> iterator = list.iterator();iterator.hasNext();){
			String str = iterator.next();
			System.out.println(str);
		}

		System.out.println("-----------------------");

		//遍历方式三 使用ListIterator迭代器
		//顺向遍历
		ListIterator<String> listIterator = list.listIterator();
		while(listIterator.hasNext()){
			String str = listIterator.next();
			System.out.println(str);
		}

		System.out.println("------------------------");

		//逆向遍历
		while(listIterator.hasPrevious()){
			String str = listIterator.previous();
			System.out.println(str);
		}

		System.out.println("------------------------");

		//遍历方式四 使用size()和get(int index)方法来实现遍历集合元素
		for (int i = 0; i < list.size(); i++) {
			String str = list.get(i);
			System.out.println(str);
		}
	}
}

5.泛型出现的原因2

早期的Object类型可以接收任意的对象类型,但是在实际使用中,会存在类型转换问题。即存在安全隐患,所以java提供了泛型来解决这个安全问题。

6.泛型的应用

泛型类:

把泛型定义在类上。

格式:public class 类名<泛型类型1,泛型类型2,...>

注意:泛型类型必须为引用类型

package com;
/**
 * 泛型类
 */
public class ObjectTool<T> {
	private T obj;

	public T getObj() {
		return obj;
	}

	public void setObj(T obj) {
		this.obj = obj;
	}
}
package com;
/**
 * 泛型类的测试
 * @author 许威威
 *
 */
public class ObjectToolTest {
	public static void main(String[] args) {
		ObjectTool<String> ot = new ObjectTool<String>();

		ot.setObj("哈哈");
		System.out.println(ot.getObj());

		ObjectTool<Integer> ot2 = new ObjectTool<Integer>();
		ot2.setObj(20);//自动装箱
		System.out.println(ot2.getObj());
	}

}

泛型方法:

把泛型定义在方法上。

格式:public <泛型类型> 返回值类型 方法名(泛型类型1,泛型类型2,...)

package cn;

public class ObjectTool {
	public void show(String str){
		System.out.println(str);
	}
	public void show(Integer i){
		System.out.println(i);
	}

}
package cn;

public class ObjectToolTest {
	public static void main(String[] args) {
		ObjectTool ot = new ObjectTool();
		ot.show("哈哈");
		ot.show(20);//自动装箱
	}

}

这样是对的,但是我如果传入的是boolean类型,Student类型,那么我只能去修改ObjectTool类了,继续增加重载方法,好麻烦。

package cn;

public class ObjectTool<T> {
	public void show(T t){
		System.out.println(t);
	}

}
package cn;

public class ObjectToolTest {
	public static void main(String[] args) {
		ObjectTool<String> ot = new ObjectTool<String>();
		ot.show("哈哈");

		ObjectTool<Integer> ot2 = new ObjectTool<Integer>();
		ot2.show(100);

		ObjectTool<Boolean> ot3 = new ObjectTool<Boolean>();
		ot3.show(true);

	}

}

但是,上面的代码是不是让泛型方法上的参数类型和类的类型一致,但是如果我类上没有泛型,方法就不能接受任意类型的数据了吗?当然不是啦。且看下面分解。

package cn;

public class ObjectTool<T> {
	public void show(T t){
		System.out.println(t);
	}

}
package cn;

public class ObjectTool1Test {
	public static void main(String[] args) {
		ObjectTool1 ot = new ObjectTool1();

		ot.show("HelloWorld");
		ot.show(100);
	}

}

泛型接口

把泛型定义在接口上。

格式:public interface 接口名<泛型类型1,泛型类型2,...>

package cn;

public interface ObjectTool3<T> {

	public  void show(T t);

}
package cn;

public class ObjectTool3Test {
	public static void main(String[] args) {
		ObjectTool3<String> ot = new ObjectTool3<String>(){
			public void show(String str){
				System.out.println(str);
			}
		};
		ot.show("呵呵");

	}

}

7.泛型之通配符

<?> 任意类型,如果没有明确,那么就是Object以及任意类型的java类。

<? extends E> 向下限定,E以及其子类

<? super E> 向上限定,E以及其父类

package cn;

import java.util.ArrayList;
import java.util.Collection;

/**
 * 泛型通配符
 * ? 	任意类型,如果没有明确,那么就是Object以及任意的java类了。
 * ? extends E  向下限定,E及其子类
 * ? super E 向上限定,E及其父类
 *
 */
class Animal{}
class Dog extends Animal{}
class Cat extends Animal{}
public class GenericDemo {
	public static void main(String[] args) {
		//泛型如果明确些的时候,前后必须一致
		Collection<Object> c = new ArrayList<Object>();
		//下面三种会报错
		//Collection<Object> c = new ArrayList<Animal>();
		//Collection<Animal> c = new ArrayList<Dog>();
		//Collection<Animal> c = new ArrayList<Dog>();

		Collection<?> c1 = new ArrayList<Animal>();
		Collection<?> c2 = new ArrayList<Dog>();
		Collection<?> c3 = new ArrayList<Cat>();

		//? extends E 向下限定,E及其子类
		Collection<? extends Animal> c4 = new ArrayList<Dog>();

		//? super E 向上限定,E及其父类
		Collection<? super Animal> c5 = new ArrayList<Object>();

	}
}
时间: 2024-08-04 19:43:52

java集合框架--泛型的相关文章

java集合框架---泛型总结

/* 泛型:指定集合类型,在运行而不是编译时时就发现问题,消除安全隐患.避免强转. */ package pack; import java.util.ArrayList; import java.util.Iterator; /*public class Main { public static void sys(Object obj) { System.out.println(obj); } public static void main(String[] args) { TreeSet<S

Java集合框架之泛型

广州疯狂软件教育Java培训,iOS培训分享 泛型:1.5版本以后出现的新特性.用于解决安全问题,是一个安全机制. 好处: 1.将运行时期出现问题ClassCaseException,转移到了编译时期. 2.方便与程序员解决问题.让运行时事情减少,安全. 3.避免了强制类型转换 泛型格式:通过<>来定义要操作的引用数据类型 什么时候写泛型: 在集合框架中和常见 只要见到<>就要定义泛型 import java.util.Comparator; import java.util.It

第10篇-JAVA 集合框架-JAVA 泛型

第10篇-JAVA 集合框架-JAVA 泛型 每篇一句 :所有的不甘,都是因为还心存梦想 初学心得: 不是每件事都注定会成功,但是每件事都值得一试 (笔者:JEEP/711)[JAVA笔记 | 时间:2017-04-15| JAVA 集合框架/JAVA 泛型 ] 1.JAVA 集合框架概念 通俗的说,集合就是一个存放数据的容器,准确的说,就是放数据对象引用的容器 数组和集合都是容器,有何不同? 数组长度固定,集合长度可变 数组只能存放相同类型的数据,集合可以存放不同类型的数据 数组可存放简单数据

一起学 Java集合框架、数据结构、泛型

一.Java 集合框架 集合框架是一个用来代表和操纵集合的统一架构.所有的集合框架都包含如下内容: 接口:是代表集合的抽象数据类型.接口允许集合独立操纵其代表的细节.在面向对象的语言,接口通常形成一个层次. 实现(类):是集合接口的具体实现.从本质上讲,它们是可重复使用的数据结构. 算法:是实现集合接口的对象里的方法执行的一些有用的计算,例如:搜索和排序.这些算法被称为多态,那是因为相同的方法可以在相似的接口上有着不同的实现. 集合接口 序号 name 接口描述 1 Collection Col

JavaSE入门学习40:Java集合框架之泛型

一Java泛型 JDK 4.0以前装入集合的类型不明确,也就是说集合中的元素,可以是任意类型的对象(对象的引用),如果把某个 对象放入集合,则会忽略它的类型,而把它当做Object处理,从而失去自己的实际类型.从集合中取出时往往需要转 型,效率低,容易产生错误.JDK 5.0泛型指的是规定了某个集合只可以存放特定类型的对象,会在编译期间进行类 型检查,也可以直接按指定类型获取集合元素. 如果我们只写一个排序方法,就能够对整型数组.字符串数组甚至支持排序的任何类型的数组进行排序,这该多 好啊.Ja

JAVA集合框架

收藏 查看我的收藏 146有用+1 56 编辑 Java,是由Sun Microsystems公司于1995年5月推出的Java程序设计语言和Java平台的总称.用Java实现的HotJava浏览器(支持Java applet)显示了Java的魅力:跨平台.动态的Web.Internet计算.从此,Java被广泛接受并推动了Web的迅速发展,常用的浏览器现在均支持Java applet.集合框架是为表示和操作集合而规定的一种统一的标准的体系结构.任何集合框架都包含三大块内容:对外的接口.接口的实

我所理解Java集合框架的部分的使用(Collection和Map)

所谓集合,就是和数组类似--一组数据.java中提供了一些处理集合数据的类和接口,以供我们使用. 由于数组的长度固定,处理不定数量的数据比较麻烦,于是就有了集合. 以下是java集合框架(短虚线表示接口,长虚线表示抽象类,实线表示类,箭头表示实现接口或者继承)(在网络上找的图,不知道原作者,侵权请联系我删除)(总之,关系很复杂,所以不用记得这个图,只是用来吓吓人而已的). 下面贴上个人理解之精简版之Collection(集)和Map(地图?暂且这么理解吧),话说思维导图蛮好用,以下是两幅思维导图

2016.3.9-3.10(java集合框架)

3.9 集合框架有什么作用? 集合框架其主要功能是用来将存储的数据以某种结构组织,并以特定的方式来访问这些数据. Java集合框架中有哪些存储方式? Java集合框架中的对象容器,按照对象在其中的存储方式,分为Set.List.和Map三种类型. Set类型对象没有顺序,且不能重复: List类型对象容器中的对象按照索引顺序排序,而且可以有重复的对象: Map类型对象容器中的元素包含一对“键对象-值对象”映射,其中键对象不能重复,值对象可以重复. 以上三种存储方式对应Java集合框架中Set.L

Java集合框架的知识总结

说明:面试准备,写的挺不错的. 转载地址: http://www.cnblogs.com/zhxxcq/archive/2012/03/11/2389611.html 1.综述 所有集合类都位于java.util包下.集合中只能保存对象(保存对象的引用变量).(数组既可以保存基本类型的数据也可以保存对象). 当我们把一个对象放入集合中后,系统会把所有集合元素都当成Object类的实例进行处理.从JDK1.5以后,这种状态得到了改进:可以使用泛型来限制集合里元素的类型,并让集合记住所有集合元素的类