集合、迭代器、增强for循环、泛型
1集合
集合是java中提供的一种容器,可以用来存储多个数据。
数组的长度是固定的。集合的长度是可变的。集合中存储的元素必须是引用类型数据。
1.1ArrayList集合存储元素(复习)
例:
public class Person {
private String name;
private int age;
public Person() {
super();
}
public Person(String name, int age) {
super();
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String toString() {
return "Person [name=" + name + ", age=" + age + "]";
}
}
import java.util.ArrayList;
public class Test1 {
public static void main(String[] args) {
//集合复习:存储基本数据类型
ArrayList<Double> arr1=new ArrayList<Double>();
arr1.add(1.6);
arr1.add(2.3);
arr1.add(3.6); for(int i=0;i<arr1.size();i++){
System.out.print(arr1.get(i)+" ");
} System.out.println(); //集合存储引用数据类型
ArrayList<Person> arr2=new ArrayList<Person>();
arr2.add(new Person("张三",18));//存匿名对象
arr2.add(new Person("小红帽",8));
arr2.add(new Person("大灰狼",55)); for(int i=0;i<arr2.size();i++){
System.out.println(arr2.get(i)); //调用toString方法,已重写
}
}
}

1.2集合的继承实现关系
常用的:

1.3 Collection接口

Collection接口是集合中的顶层接口,它中定义的所有功能子类都可以使用。
Collection 是层次结构中的根接口。Collection 表示一组对象,这些对象也称为 collection 的元素。一些 collection 允许有重复的元素,而另一些则不允许。一些 collection 是有序的,而另一些则是无序的。
(这里的有序不是指元素在值上的排序,而是指存、取的顺序一致,怎么存就怎么取,有索引下标)
1.3.1 Collection常用方法
Collection是接口,所以全是抽象方法。
需要用多态new对象。

例:
import java.util.Collection;
import java.util.ArrayList; public class CollectionTest {
public static void main(String[] args) {
//创建对象
Collection<String> col=new ArrayList<String>(); //添加元素
col.add("中国");
col.add("你好");
col.add("java"); //判断集合中是否包含某元素
boolean flag=col.contains("java");
if(flag){
System.out.println("true,包含元素");
} //移除元素
boolean dels=col.remove("你好"); //这个是返回布尔值
if(dels){
System.out.println("移除成功");
} //向下转型
ArrayList<String> arr=null; //定义成全局,不然遍历时取不到
if(col instanceof ArrayList){
arr=(ArrayList<String>)col;
} System.out.println(); //遍历
System.out.println("遍历结果:");
for(int i=0;i<arr.size();i++){
System.out.print(arr.get(i)+" ");
} System.out.println();
System.out.println(); //转成数组
Object[] strs=col.toArray();
System.out.println("遍历数组:");
for(int i=0;i<strs.length;i++){
//String str=(String)strs[i];//这里是Object型数组,如果想转成String数组,不能直接强转,要给元素转型
System.out.print(strs[i]+" ");
} System.out.println();
System.out.println(); //清除内容
col.clear();
System.out.println("清除后:");
for(int i=0;i<arr.size();i++){
System.out.print(arr.get(i)+" ");
}
}
}

注意:
1注意方法的返回值类型
2一定要指定泛型,不然还要强转
例:会有警告


1.4 Iterator迭代器
1.4.1定义
java中提供了很多个集合,它们在存储元素时,采用的存储方式不同。
List有序(有下标索引),set无序(看上面的继承体系图)
要取出这些集合中的元素,可通过一种通用的获取方式来完成。
迭代定义:
Collection集合元素的通用获取方式:在取元素之前先要判断集合中有没有元素,如果有,就把这个元素取出来,继续再判断,如果还有就再取出出来。一直把集合中的所有元素全部取出。这种取出方式专业术语称为迭代。
集合中把这种取元素的方式描述在Iterator接口中。
1.4.2 Iterator接口的常用方法

hasNext()方法:用来判断集合中是否有下一个元素可以迭代。如果返回true,说明可以迭代。
next()方法:用来返回迭代的下一个元素,并把指针向后移动一位。

1.4.3 Iterator接口的对象

Iterable对象里有一个iterator() 方法,可以返回Iterator对象,Collection继承了这个方法,那么其子类或实现类就都有了这个方法,可以用这个方法创建Iterator对象。

例:(Iterator接口也可以使用<>来控制迭代元素的类型的)
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator; public class IteratorTest {
public static void main(String[] args) {
Collection<Integer> col=new ArrayList<Integer>();
col.add(1);
col.add(2);
col.add(3);
col.add(4); //获取迭代器对象
Iterator<Integer> it=col.iterator(); //循环
while(it.hasNext()){
int i=it.next(); //自动拆箱
System.out.println(i);
}
}
}

注意:
1)next()只能用一次,再调用,指针还会往后走,想判断,要先把值获取到,再判断值。
例:
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator; public class I2 {
public static void main(String[] args) {
Collection<Integer> col=new ArrayList<Integer>();
col.add(1);
col.add(2);
col.add(3);
col.add(4); //获取迭代器对象
Iterator<Integer> it=col.iterator(); //用循环
while(it.hasNext()){
if(it.next()==2){
System.out.println(it.next());
}
}
}
}

说明next()又向后走了,所以要改成这样:
while(it.hasNext()){
int i=it.next();
if(i==2){
System.out.println(i);
}
}

还可以for循环,但不常用
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator; public class I2 {
public static void main(String[] args) {
Collection<Integer> col=new ArrayList<Integer>();
col.add(1);
col.add(2);
col.add(3);
col.add(4); for(Iterator<Integer> it=col.iterator();it.hasNext();){
System.out.println(it.next());
}
}
}
2)在进行集合元素取出时,如果集合中已经没有元素了,还继续使用迭代器的next方法,将会发生java.util.NoSuchElementException没有集合元素的错误。
例:


1.5集合元素的向下转型
集合中可以存储任何对象,那么存放进去的数据就不再是原来的类型了,而是提升成了Object。
如果集合中存放的是多个对象,这时进行向下转型会发生类型转换异常。


3增强for循环
增强for循环是JDK1.5以后出来的一个高级for循环,专门用来遍历数组和集合的。它的内部原理其实是个Iterator迭代器,所以在遍历的过程中,不能对集合中的元素进行增删操作。
3.1格式:
for(元素的数据类型 变量 : Collection集合or数组){
}
例:
import java.util.ArrayList;
import java.util.Collection; public class forTest {
public static void main(String[] args) {
Collection<String> col=new ArrayList<String>();
col.add("你好");
col.add("快乐"); //使用增强for
for(String str:col){
System.out.println(str); //取到的就是String对象
} //使用增强for遍历数组
int[] arr={1,2,3,4,5};
for(int i:arr){
System.out.print(i+" "); //i就是每个值
}
}
}

3.2对比:
1)迭代器只能迭代集合,增强for能遍历集合和数组。
2)新for循环必须有被遍历的目标。目标只能是Collection或者是数组。只用来遍历,不进行任何操作。
遍历数组时,如果仅为遍历,可以使用增强for。
如果要对数组的元素进行操作,使用老式for循环,(因为可以通过下标操作)
3.3总结:
遍历集合:三种方式
遍历数组:两种方式
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator; public class Test1 {
public static void main(String[] args) {
showList();
showArr();
} public static void showList(){
Collection<String> col=new ArrayList<String>();
col.add("abc");
col.add("ABC");
col.add("12345"); //for循环遍历
System.out.println("for循环遍历集合:");
ArrayList<String> arr=null;
if(col instanceof ArrayList){
arr=(ArrayList<String>)col;
}
for(int i=0;i<arr.size();i++){
System.out.print(arr.get(i)+"\t");
} //迭代器
System.out.println();
System.out.println("迭代器集合:");
Iterator<String> it=col.iterator();
while(it.hasNext()){
System.out.print(it.next()+"\t");
} //增强for
System.out.println();
System.out.println("增强for遍历集合:");
for(String str:col){
System.out.print(str+"\t");
}
} public static void showArr(){
System.out.println();
int[] arr={1,2,3,4,5}; System.out.println("普通for遍历数组:");
for(int i=0;i<arr.length;i++){
System.out.print(arr[i]+" ");
} System.out.println();
System.out.println("增强for遍历数组:");
for(int i:arr){
System.out.print(i+" ");
}
}
}

4泛型
前面一些例子,集合中是可以存放任意对象的,提升成Object类型,这时容易发生
ClassCastException类型转换异常,泛型就是为了解决这个问题。
4.1定义
使用集合时,必须明确集合中元素的类型,这种方式称为泛型。
泛型,用来灵活地将数据类型应用到不同的类、方法、接口当中。将数据类型作为参数进行传递。
定义格式:
修饰符 class 类名<代表泛型的变量> { }
修饰符 interface接口名<代表泛型的变量> { }
E就是一个变量,是element的意思,在什么时候明确:
1)实现或继承时明确
Public class MyList<String> implements list<E>{}
Public class MyList<E> implements list<String>{}
2)new对象时明确
Api中带<E>的方法都是如此
4.2使用泛型的好处
将运行时期的ClassCastException,转移到了编译时期变成了编译失败。避免了类型强转的麻烦。
Tips:
泛型:又叫伪泛型,编译时不进.class文件 (注释也不进)
只在java代码中对集合存储数据类型进行约束
4.3泛型通配符
当定义方法时,无法确定具体集合中的元素类型是什么,可以使用泛型通配符<?>,用来占空。
例:
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator; public class Test02 {
public static void main(String[] args) {
ArrayList<String> arr=new ArrayList<String>();
arr.add("中国");
arr.add("java"); HashSet<Integer> set=new HashSet<Integer>();
set.add(1);
set.add(2); showAll(arr);
showAll(set);
} //泛型通配符
public static void showAll(Collection<?> col){
Iterator<?> it=col.iterator();
while(it.hasNext()){
System.out.println(it.next());
}
}
}

但是一旦使用泛型的通配符后,只能使用Object类中的共性方法,集合中元素自身方法无法使用。(可以向下转型,但是太麻烦了)
4.4泛型限定
泛型里面没有向上向下转型的概念。所以要定好。
限定泛型的上限:
格式:? extends E
? 代表接收E类型或者E的子类型的元素
限定泛型的下限:
格式:? super E
? 代表接收E类型或者E的父类型的元素(父类型,不只是父类)
例:
//员工类
public abstract class Emp {
public abstract void work();
}
//经理类
public class Manager extends Emp{
public void work() {
System.out.println("经理管理");
}
}
//服务员类
public class Waiter extends Emp{
public void work() {
System.out.println("服务员上菜");
}
}
//厨师类
public class Cooker extends Emp{
public void work() {
System.out.println("厨师炒菜");
}
}
import java.util.ArrayList;
public class Test03 {
//四个类:员工,经理,服务员,厨师 都有work方法
//传入三个类调用其work方法
public static void main(String[] args) {
Manager m=new Manager();
ArrayList<Manager> arr1=new ArrayList<Manager>();
arr1.add(m);
Waiter w=new Waiter();
ArrayList<Waiter> arr2=new ArrayList<Waiter>();
arr2.add(w);
Cooker c=new Cooker();
ArrayList<Cooker> arr3=new ArrayList<Cooker>();
arr3.add(c);
working(arr1);
working(arr2);
working(arr3);
ArrayList<Object> arr4=new ArrayList<Object>();
arr4.add("这是一个Object类型的数据");
arr4.add("这是一个Object类型的数据2");
working2(arr4);
}
public static void working(ArrayList<? extends Emp> arr){ //限定泛型的上限
Emp emp=arr.get(0);
emp.work();
}
public static void working2(ArrayList<? super Emp> arr){ //限定泛型的下限
for(int i=0;i<arr.size();i++){
System.out.println(arr.get(i));
}
}
}

这里如果是接口,也可以用extends。
集合、迭代器、增强for循环、泛型的更多相关文章
- java基础第十二篇之集合、增强for循环、迭代器和泛型
Collection接口中的常用方法: * 所有的子类子接口都是具有的 * 集合的方法:增删改查 * * public boolean add(E e);//添加元素 返回值表示是否添加成功 * pu ...
- JavaSE Collections类 , Iterator迭代器 , 增强for循环
Collections 它是集合的工具类,为集合体系扩展了一些其他的方法.类中都是静态的方法,可以使用类名直接调用. 可变参数 在JDK1.5之后,如果我们定义一个方法需要接受多个参数,并且多个参数类 ...
- 集合、增强for、泛型
Collection集合:Collection是层次结构中的根接口,存储的元素为对象,(也就是说只能存储引用数据类型,不能存储基础数据类型),具体可查询API.集合与数组的区别:1.集合只能存放引用数 ...
- 阶段1 语言基础+高级_1-3-Java语言高级_04-集合_01 Collection集合_7_增强for循环
collections实现了interable接口.实现了interable接口就可以使用Foreach int i是临时 变量
- 18_集合框架_第18天_集合、Iterator迭代器、增强for循环 、泛型_讲义
今日内容介绍 1.集合 2.Iterator迭代器 3.增强for循环 4.泛型 01集合使用的回顾 *A:集合使用的回顾 *a.ArrayList集合存储5个int类型元素 public stati ...
- 01 语言基础+高级:1-6 集合_day02【Collection、泛型】
day02[Collection.泛型] 主要内容 Collection集合 迭代器 增强for 泛型 教学目标 能够说出集合与数组的区别 说出Collection集合的常用功能 能够使用迭代器对集合 ...
- 增强for循环(forearch)
增强for循环是为了简化在遍历数组需要先获得数组的长度或者在遍历集合中的元素的时候需要使用迭代器的操作. 引入时间:JDK1.5 语法格式: for(数据类型 变量 :需要迭代的数组或者集合){ } ...
- Java流程控制:增强for循环,break&continue,打印99乘法表
增强for循环:java5引入了一种主要用于数组或集合的增强for循环for(声明语句:表达式){//代码句子} 声明语句:声明新的局部变量,该变量的类型必须和数组元素的类型匹配.其作用域限定在循环语 ...
- JAVA基础之集合、Iterator迭代器、泛型及增强for循环
个人理解: 对于集合,首先要明确的是最顶层的接口是Collection接口类,其包含一些基本的方法以便子类调用,不过在定义的时候最好定义好数据类型,以免遍历时还得必须进行向上转型:特别注意的是其没有关 ...
随机推荐
- 监测GPU使用情况命令
每2秒监测一次:watch -n 2 nvidia-smi
- [poj3107/poj2378]Godfather/Tree Cutting树形dp
题意:求树的重心(删除该点后子树最大的最小) 解题关键:想树的结构,删去某个点后只剩下它的子树和原树-此树所形成的数,然后第一次dp求每个子树的节点个数,第二次dp求解答案即可. 此题一开始一直T,后 ...
- 正则表达式 LINUX
正则表达式 热身 正则表达式(regular expression)描述了一种字符串匹配的模式,可以用来检查一个串是否含有某种子串.将匹配的子串做替换或者从某个串中取出符合某个条件的子串等. 例如 g ...
- storm事件管理器EventManager源码分析-event.clj
storm事件管理器定义在event.clj中,主要功能就是通过独立线程执行"事件处理函数".我们可以将"事件处理函数"添加到EventManager的阻塞队列 ...
- Spring入门第十三课
通过FactoryBean来配置Bean package logan.spring.study.factoryBean; public class Car { private String brand ...
- jquery、javascript实现(get、post两种方式)跨域解决方法
一.实现get方式跨域请求数据 浏览器端 <script> $(document).ready(function(){ $.ajax({ url: "http://www.xxx ...
- HDU - 6113 2017百度之星初赛A 度度熊的01世界
度度熊的01世界 Accepts: 967 Submissions: 3064 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 327 ...
- linux端口netstat
netstat -aptn命令行,查看所有开启的端口号 netstat -nupl 查看所有udp端口号 netstat -ntpl 查看所有tcp端口号 查看某服务占用的端口情况,比 ...
- 洛谷P2217 [HAOI2007]分割矩阵
P2217 [HAOI2007]分割矩阵 题目描述 将一个a*b的数字矩阵进行如下分割:将原矩阵沿某一条直线分割成两个矩阵,再将生成的两个矩阵继续如此分割(当然也可以只分割其中的一个),这样分割了(n ...
- 【微信小程序】开发实战 之 「数据缓存API」解析
每个小程序都可以有自己的本地缓存,可以通过 数据缓存的API 实现对本地缓存进行 设置.获取和清理.本地缓存最大为10M.localStorage是永久存储的,但我们不建议将关键信息都放在localS ...