java 增强for循环与泛型
一 增强for循环
增强for循环是JDK1.5以后出来的一个高级for循环,专门用来遍历数组和集合的。它的内部
原理其实是个Iterator迭代器,所以在遍历的过程中,不能对集合中的元素进行增删操作。
格式:
for(元素的数据类型 变量 : Collection集合or数组){
}
它用于遍历Collection和数组。通常只进行遍历元素,不要在遍历的过程中对集合元素进行增删操作。
练习一:遍历数组int[] arr = new int[]{11,22,33}; for (int n : arr) {//变量n代表被遍历到的数组元素
System.out.println(n);
}
练习二:遍历集合
Collection<String> coll = new ArrayList<String>();
coll.add("a1");
coll.add("a2");
coll.add("a3");
coll.add("a4");
for(String str : coll){//变量Str代表被遍历到的集合元素
System.out.println(str);
}
增强for循环和老式的for循环有什么区别?
注意:新for循环必须有被遍历的目标。目标只能是Collection或者是数组。
建议:遍历数组时,如果仅为遍历,可以使用增强for如果要对数组的元素进行操作,
使用老式for循环可以通过角标操作。
二 泛型
1.泛型的引入
集合中是可以存放任意对象的,只要把对象存储集合后,那么这时他们都会被提升成Object类型。
当我们在取出每一个对象,并且进行相应的操作,这时必须采用类型转换。比如下面程序:
public class GenericDemo {
public static void main(String[] args) {
List list = new ArrayList();
list.add("abc");
list.add("oracle");
list.add(5);//由于集合没有做任何限定,任何类型都可以给其中存放
Iterator it = list.iterator();
while(it.hasNext()){
//需要打印每个字符串的长度,就要把迭代出来的对象转成String类型
String str = (String) it.next();
System.out.println(str.length());
}
}
}
程序在运行时发生了问题java.lang.ClassCastException
为什么会发生类型转换异常呢?我们来分析下:
由于集合中什么类型的元素都可以存储。导致取出时,如果出现强转就会引发运行时 ClassCastException。
怎么来解决这个问题呢?使用集合时,必须明确集合中元素的类型。这种方式称为:泛型。
2.泛型的定义与使用
泛型,用来灵活地将数据类型应用到不同的类、方法、接口当中。将数据类型作为参数进行传递。
(1)含有泛型的类
定义格式:修饰符 class 类名<代表泛型的变量> { }
例如,API中的ArrayList集合:
class ArrayList<E>{
public boolean add(E e){ }
public E get(int index){ }
}
使用格式:创建对象时,确定泛型的类型
例如,ArrayList<String> list = new ArrayList<String>();
此时,变量E的值就是String类型
class ArrayList<String>{
public boolean add(String e){ }
public String get(int index){ }
}
例如,ArrayList<Integer> list = new ArrayList<Integer>();
此时,变量E的值就是Integer类型
class ArrayList<Integer>{
public boolean add(Integer e){ }
public Integer get(int index){ }
}
(2)含有泛型的接口
定义格式:修饰符 interface接口名<代表泛型的变量> { }
例如,API中的Iterator迭代器接口
public interface Iterator<E> {
public abstract E next();
}
使用格式:
定义类时确定泛型的类型
例如
public final class Scanner implements Iterator<String> {
public String next(){
}
}
此时,变量E的值就是String类型。
始终不确定泛型的类型,直到创建对象时,确定泛型的类型
例如
ArrayList<String> list = new ArrayList<String>();
Iterator<String> it = list.iterator();
此时,变量E的值就是String类型。
public interface Iterator<String> {
public abstract String next();
}
3.使用泛型的好处
将运行时期的ClassCastException,转移到了编译时期变成了编译失败。
避免了类型强转的麻烦。
演示下列代码:
public class GenericDemo {
public static void main(String[] args) {
List<String> list = new ArrayList<String>();
list.add("abc");
list.add("oracle");
//list.add(5);//当集合明确类型后,存放类型不一致就会编译报错
//集合已经明确具体存放的元素类型,那么在使用迭代器的时候,迭代器也同样会知道具体遍历元素类型
Iterator<String> it = list.iterator();
while(it.hasNext()){
String str = it.next();
//当使用Iterator<String>控制元素类型后,就不需要强转了。获取到的元素直接就是String类型
System.out.println(str.length());
}
}
}
4.泛型通配符
泛型是在限定数据类型,当在集合或者其他地方使用到泛型后,那么这时一旦明确泛型的数据类型,
那么在使用的时候只能给其传递和数据类型匹配的类型,否则就会报错。
代码演示:
定义迭代集合元素的方法
public static void printCollection(Collection<Person> list) {
Iterator<Person> it = list.iterator();
while (it.hasNext()) {
System.out.println(it.next());
}
}
调用方法
Collection<Student> list = new ArrayList<Student>();
printCollection(list);
上面调用方法语句属于语法错误,因为泛型限定不一致。方法要的是Collection<Person>类型,
传入的是Collection<Student>,二者类型不匹配。
上述定义的printCollection方法中,由于定义的是打印集合的功能,应该是可以打印任意集合中
元素的。但定义方法时,根本无法确定具体集合中的元素类型是什么。为了解决这个"无法确定具体
集合中的元素类型"问题,java中,为我们提供了泛型的通配符<?>。
对上面的方法,进行修改后,实现了可迭代任意元素类型集合的方法
public static void printCollection(Collection<?> list) {
Iterator<?> it = list.iterator();
while (it.hasNext()) {
System.out.println(it.next());
}
}
总结:
当使用泛型类或者接口时,传递的数据中,泛型类型不确定,可以通过通配符<?>表示。但是一旦使
用泛型的通配符后,只能使用Object类中的共性方法,集合中元素自身方法无法使用。
5.泛型限定
如果想要对被打印的集合中的元素类型进行限制,只在指定的一些类型,进行打印。怎么做呢?
要解决这个问题,我们就要学习泛型的限定。
限定泛型的上限:
格式:? extends E
? 代表接收E类型或者E的子类型的元素
例如,泛型限定为:? extends Person
则 ? 代表接收Person类型或者Person子类型的元素
限定泛型的下限:
格式:? super E
? 代表接收E类型或者E的父类型的元素
例如,泛型限定为:? super Student
则 ? 代表接收Student类型或者Student父类型的元素
练习:修改下面的方法,使该方法可以打印学生和工人的集合
class Student extends Person{ }
class Worker extends Person{ }
public static void printCollection(Collection<?> list) {
Iterator<?> it = list.iterator();
while (it.hasNext()) {
System.out.println(it.next());
}}
分析一下,我们可以找到学生和工人的共性类型Person。那么,泛型的限定可以这样书写:
? extends Person : 接收Person类型或者Person的子类型。修改方法如下:
public static void printCollection(Collection<? extends Person> list) {
Iterator<? extends Person> it = list.iterator();
while (it.hasNext()) {
System.out.println(it.next());
}
}
java 增强for循环与泛型的更多相关文章
- Java 增强 for 循环
Java 增强 for 循环 Java5 引入了一种主要用于数组的增强型 for 循环. Java 增强 for 循环语法格式如下: for(声明语句 : 表达式) { //代码句子 } 声明语句:声 ...
- java增强for循环中获取index
java增强for循环中获取index http://rensanning.iteye.com/blog/2003205
- java基础(18):集合、Iterator迭代器、增强for循环、泛型
1. 集合 1.1 集合介绍 集合,集合是java中提供的一种容器,可以用来存储多个数据. 在前面的学习中,我们知道数据多了,可以使用数组存放或者使用ArrayList集合进行存放数据.那么,集合和数 ...
- 18_集合框架_第18天_集合、Iterator迭代器、增强for循环 、泛型_讲义
今日内容介绍 1.集合 2.Iterator迭代器 3.增强for循环 4.泛型 01集合使用的回顾 *A:集合使用的回顾 *a.ArrayList集合存储5个int类型元素 public stati ...
- 集合、迭代器、增强for循环、泛型
1集合 集合是java中提供的一种容器,可以用来存储多个数据. 数组的长度是固定的.集合的长度是可变的.集合中存储的元素必须是引用类型数据. 1.1ArrayList集合存储元素(复习) 例: pub ...
- [Day18]集合框架Collection、迭代器、增强for循环以及泛型
1.集合 1.1集合-本身是一个存储的容器 集合类的基本接口是Collection接口,这个接口有两个基本方法 (1)boolean add(E element) 用于向集合中添加元素,如果添加元素确 ...
- JAVA增强for循环
作用:简化数组和集合的遍历 格式:for(元素数据类型 变量 :数组或者集合) 例子: Map map=new HashMap; for(Object obj :map.keySet()){ Obj ...
- java 增强for循环对于空集和null的判断
List<String> list = null; for (String str : list) {//会报空指针异常 System.out.println(str); } List&l ...
- Java基础系列(24)- 增强for循环
增强for循环 这里我们先只是见一面,做个了解,之后数组部分会重点使用 Java5引入了一种主要用于数组或集合的增强型for循环 Java增强for循环语法格式如下 for(声明语句:表达式){ // ...
随机推荐
- ffmpeg播放器实现详解 - 框架搭建
ffplay是ffmpeg源码中一个自带的开源播放器实例,同时支持本地视频文件的播放以及在线流媒体播放,功能非常强大. FFplay: FFplay is a very simple and port ...
- db2数据库基本添加删除表字段总结
1.添加字段 alter table [table_name] add [column_name] [column_type] 2.更改字段类型 alter table [table_name] a ...
- Python Ethical Hacking - BACKDOORS(1)
REVERSE_BACKDOOR Access file system. Execute system commands. Download files. Upload files. Persiste ...
- 想用@Autowired注入static静态成员?官方不推荐你却还偏要这么做
生命太短暂,不要去做一些根本没有人想要的东西.本文已被 https://www.yourbatman.cn 收录,里面一并有Spring技术栈.MyBatis.JVM.中间件等小而美的专栏供以免费学习 ...
- 评测Loki日志工具
评测Loki日志工具 目录 评测Loki日志工具 部署Loki 配置grafana 总结: 优势: 劣势: 本文仅对Loki进行简单评测,不涉及原理和细节. 部署Loki Loki是grafana团队 ...
- 【Python学习笔记三】一个简单的python爬虫
这里写爬虫用的requests插件 1.一般那3.x版本的python安装后都带有相应的安装文件,目录在python安装目录的Scripts中,如下: 2.将scripts的目录配置到环境变量pa ...
- 虚拟DOM Vitural DOM Tree
提起Virtual DOM,总是给人一种高深莫测的感觉,大家都知道它比DOM快.那么Virtual DOM到底是何方神圣呢?在深入理解Virtual DOM之前,先让我们回顾一下DOM. 一.什么 ...
- Problem C: 计算机类
Description 定义一个Computer类,有两个属性: 1. 字符串属性name,用于表示计算机的名字. 2. 静态整型属性cnt,用于记录产生的计算机对象的个数. 至少有如下成员函数: 1 ...
- 使用java实现希表的基础功能
用java代码完成哈希表数据结构的简单实现, 以公司雇员的添加修改作为模拟实例 具体代码如下: package com.seizedays.hashtable; import java.util.Sc ...
- Druid 连接池
记录Druid 连接池简单用法 package Utils; import com.alibaba.druid.pool.DruidDataSourceFactory; import javax.sq ...