泛型:是一种未知的数据类型,当我们不知到使用什么数据类型的时候可以使用泛型
泛型也可以看成是一个变量,用来接收数据类型:
E e :Element 元素 | T E Type 类型
ArrayList集合在定义的时候,不知道集合中都会有什么数据类型,所以类型使用泛型
public class ArrayList{
public boolean add(E e){}
public E get(int index){}
}
创建集合对象的时候就会确定泛型的数据类型
会把数据类型作为参数传递,赋值给泛型.
使用泛型的好处:
=================
public class FanXingCls {
public static void main(String[] args) {
// show01();
show02();
}
/*
* 创建集合对象,不使用泛型
* 好处: 集合不使用泛型,默认的了行就是Object类型,可以存储任意类型的数据
* 弊端: 不安全,会引发异常
*
*/
private static void show01(){
//不使用泛型创建集合。
ArrayList list = new ArrayList();
list.add("abc");
list.add(1);
//使用迭代器遍历集合
//获取迭代器
Iterator it = list.iterator();
it.hasNext();
while(it.hasNext()){
//取出元素也是Object类型
Object obj = it.next();
System.out.println(obj);
//想要使用String类特有的方法length获取字符串的长度,不能使用
//多态 Object obj = "abc";
//需要向下转型
//会抛出java.lang.ClassCastException,不能把Integer转换为String,所以不使用泛型不安全
String s = (String) obj;
System.out.println(s.length());
}
}
/*
* 创建集合对象,使用泛型
* 好处:避免了类型转换异常,,存储什么类型,就取出什么类型
* 把运行期异常(代码运行之后会抛出的异常),提升到编译器
* 弊端:存储的类型必须一致
*/
private static void show02(){
ArrayList<String> list = new ArrayList<>();
list.add("abc");
list.add("bcd");
//使用迭代器遍历集合
//也可用上面的是方法遍历.
for (String string : list) {
System.out.println(string);
System.out.println(string.length());
}
}
}
泛型类
定义一个含有泛型的类,模拟ArrayList集合
泛型是一个未知的数据类型,当我们不确定是用什么类型的时候,可以使用泛型
泛型可以使用任意的数据类型,可以使用Integer,String,Student.
这样就定义了一个含有泛型的类
====================
//含有泛型的类。
public class GenerClass<E> {
private E name;
public E getName() {
return name;
}
public void setName(E name) {
this.name = name;
}
}
-------------------------------
//使用含有泛型的类,定义类,使用的时候传递什么类型的类就是什么类型的类。
public class GenerClaTest {
public static void main(String[] args) {
// TODO Auto-generated method stub
//不写泛型默认为Object类型
GenerClass gc = new GenerClass();
gc.setName("字符串");
Object name = gc.getName();
//创建GennericClass对象,泛型使用Integer类型
//使用时添加泛型
GenerClass<Integer> gc2 = new GenerClass<>();
gc2.setName(1);
Integer name2 = gc2.getName();
//使用字符串
GenerClass<String> gc3 = new GenerClass<>();
gc3.setName("张天爱");
String name3 = gc3.getName();
}
}
=======================
import java.util.ArrayList;
import java.util.Collection;
/*
* 了解怎么使用这些东西。
* 泛型的上限限定和下限限定:
* 上限限定: ? extend E 代表使用的泛型只能是E类型的子类或本身
* 下限限定: ? super E 代表使用的泛型只能是E类型的父类或本身
*
*/
public class FanXingGeneric {
public static void main(String[] args) {
Collection<Integer> list1 = new ArrayList<Integer>();
Collection<String> list2 = new ArrayList<String>();
Collection<Number> list3 = new ArrayList<Number>();
Collection<Object> list4 = new ArrayList<Object>();
getElement(list1);
// getElement(list2);//报错String类型与Number类型无关系
getElement(list3);
// getElement(list4);//报错Object类型是Number的父类
//下面的逻辑原理类同.
/*
* 类与类之间的继承关系
* Integer extends Number extends Object
* String extends Object
*
*/
}
//泛型的上限,此时的泛型? 必须是number类型或者是number类型的子类
private static void getElement(Collection<? extends Number> list1) {
// TODO Auto-generated method stub
}
//泛型的上限,此时的泛型? 必须是number类型或者是number类型的父类
private static void getElement2(Collection<? super Integer> list1) {
// TODO Auto-generated method stub
}
}
-------------------------------------------
import java.util.ArrayList;
import java.util.Iterator;
/*
* 泛型的通配符:
* ?代表任意的数据类型
*
* 不能创建对象使用
* 只能作为方法的参数使用
*
*/
public class GenericCls {
public static void main(String[] args) {
//固定类型的泛型。
ArrayList<Integer> list01 = new ArrayList<>();
list01.add(1);
list01.add(2);
ArrayList<String> list02 = new ArrayList<>();
list02.add("a");
list02.add("b");
printArray(list01);
printArray(list02);
//public static void printArray(ArrayList<Integer> list){
//当这个泛型确定的时候,这两个参数的方法可定有一个报错,所以我们可以使用泛型通通配符来解决
}
/*
* 定义一个方法,能遍历所有类型的ArrayList集合
* 这时候我们不知道ArrayList集合使用什么类型数据,可以使用泛型通配符来接收数据类型.
* 泛型没有继承概念的
*
*/
//定义一个方法,代表泛型,这个泛型可以传递任何的数据类型,用通配符来完成。
public static void printArray(ArrayList<?> list){
//使用迭代器遍历集合,遍历集合
Iterator<?> it = list.iterator();
while(it.hasNext()){
//it.next()方法,取出的元素是Object,可以接收任意的数据类型
Object o = it.next();
System.out.println(o);
}
for (Object object : list) {
System.out.println("增强for"+object);
}
}
}
定义含有泛型的方法:
泛型定义在方法的修饰符和返回值之间
格式:
修饰符 <泛型> 返回值类型 方法名(参数列表(使用泛型)){
方法体;
}
含有泛型的方法,在调用方法的时候确定泛型的数据类型
传递什么类型的参数,反省就是什么类型.
===================
public class GennerMethod {
//定义一个含有泛型的方法
public <M> void method01(M m){
System.out.println(m);
}
//定义一个含有泛型的静态方法
public static <S> void method02(S s){
System.out.println(s);
}
}
------------------------------
public class GennerMethodTest {
public static void main(String[] args) {
// TODO Auto-generated method stub
GennerMethod gm = new GennerMethod();
/*
* 传递什么类型的数据
* 泛型就是什么类型
*
*/
gm.method01(10);
gm.method01("abc");
gm.method01(true);
gm.method02("静态方法,不建议创建对象使用,通过类名.方法名使用");
GennerMethod.method02("静态方法");
GennerMethod.method02(1);
}
}
===========================
泛型接口:
==========================
public interface GennerInterface<I> {
public abstract void method(I i);
}
-----------------------------------
/*
* 含有泛型的接口第一种使用方式:
* 第一种使用方式;定义接口的实现类,实现接口,指定接口的泛型
* public interface Iterator<E>{
* E next();
* }
* Scanner类实现了Iterator接口,并指定接口泛型为字符串,所以重写的next方法泛型默认就是String
* public final class Scanner implements Iterator<String>{
* public String next(){}
* }
*
*/
//一想到接口,就必须想到的是实现类。
public class GennerInterfaceImpl implements GennerInterface<String>{
//传递指定好的类型。
@Override
public void method(String i) {
// TODO Auto-generated method stub
}
}
-----------------------------------
/*
* 第二种使用方式:
* 接口是用什么泛型,实现类就是用什么泛型,类跟着接口走
* 就相当于含有泛型的类,创建对象的时候确定泛型的类型
* public interface List<E>{
* boolean add(E e);
* E get (int index);
* }
* public class ArrayList<E> implements List<E>{
* public boolean add(E e);
* public E get(int index);
* }
*
*
*
*/
public class GennerInterfaceImpl02<I> implements GennerInterface<I>{
@Override
public void method(I i) {
// TODO Auto-generated method stub
System.out.println(i);
}
}
------------------------------------
/*
* 测试含有泛型的接口
*
*
*/
public class GennerInterfaceTest {
public static void main(String[] args) {
// TODO Auto-generated method stub
//创建,先前指定好类型
GennerInterfaceImpl gif = new GennerInterfaceImpl();
gif.method("字符串");
//创建,现在指定类型
GennerInterfaceImpl02<Integer> gif2 = new GennerInterfaceImpl02<>();
gif2.method(10);
//创建,随后现在指定类型。
GennerInterfaceImpl02<Double> gif3 = new GennerInterfaceImpl02<>();
gif3.method(3.141592653);
}
}
=============================
迭代器
java.util.Iterator接口:迭代器(对集合进行遍历)
Iterator接口介绍:
迭代器:一种通用取出元素的方式
在取出元素之前先判断集合中有没有元素,如果有就把这个元素取出来,继续在判断,
一直把集合中所有元素全部取出来。
通用方法:
boolean hasNext();
如果仍有元素可以迭代,则返回true
E next() 返回迭代的下一个元素 取出集合中下一个元素
Iterator接口,我们无法直接使用,所以需要使用接口的实现类对象
Collection接口有一个方法,叫iterator() 这个方法返回的就是迭代器的是实现类对象
Iterators iterator() 返回在此 collection 的元素上进行迭代的迭代器
迭代器的使用步骤:
使用集合中的方法iterator 获取迭代器的实现类对象,使用Iterator接口接收(多态)
使用Iterator接口中的方法hashNext()判断有没有下一个元素
使用Iterator接口中的方法next取出集合中的下一个元素.
Iterator接口也是有泛型的,迭代器的泛型也跟着集合走,集合是什么反省,迭代器就是什么泛型。
=======================
public class IteratorCls {
public static void main(String[] args) {
Collection<String> coll = new ArrayList<>();
//往集合中添加元素
coll.add("马化腾");
coll.add("马云");
coll.add("刘强东");
System.out.println("-------------------------------");
//获取迭代器 coll.iterator(); 多态
Iterator<String> it = coll.iterator();
//创建一个集合
/*
* 我们发现代码是一个重复的过程
* 不知道集合中有多少个元素,所以使用while循环.
* 循环结束的条件hasNext方法返回true
*
*/
while(it.hasNext()){
String e = it.next();
System.out.println(e);
}
//下面没有元素所以会报错.
System.out.println("------------------------------------");
for(Iterator<String> it2 = coll.iterator();it2.hasNext();){
String e = it2.next();
System.out.println(e);
}
//使用Iterator接口中的方法hashNext()判断有没有下一个元素
boolean b = it.hasNext();
//把元素取出来
String next = it.next();
System.out.println(next);
//这一步是还有接着取。
b = it.hasNext();
//把元素取出来
next = it.next();
System.out.println(next);
b = it.hasNext();
//把元素取出来
next = it.next();
System.out.println(next);
//我们发现这样取有点麻烦
//而且没有元素.在取出元素抛出NoSuchElementException 没有元素异常.
}
}
=========================
增强for
增强for循环:的曾使用的是迭代器,使用for循环的格式,简化了迭代的写法
是JDK1.5之后出现的新特性
所有单例集合都可以使用增强for
Collection extends Iterable
public interface Iterable:实现这个接口允许对象成为"foreach"语句的目标对象
格式(集合/数组的数据类型 变量名 : 集合名/数据名){
syso(变量名)
}
遍历的目标只能是集合和数组.
=================
public class ZengQiangFor {
public static void main(String[] args) {
demo01();
demo02();
}
//遍历数组
private static void demo01(){
int[] arr = {1,2,3,4,5};
for(int i : arr){
System.out.println(i);
}
}
//遍历集合。
private static void demo02(){
ArrayList<String> list = new ArrayList<>();
list.add("aaa");
list.add("bbb");
list.add("ccc");
list.add("ddd");
for (String s : list) {
System.out.println(s);
}
}
}