Java的Iterator迭代器补充,增强for循环,泛型,List接口,set接口

Posted 孙崇武

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java的Iterator迭代器补充,增强for循环,泛型,List接口,set接口相关的知识,希望对你有一定的参考价值。

1、Iterator迭代器:
(1)类型转换异常:ClassCastException;集合中存放的是多个对象时,在强转时会出现;

package com.oracle.demo01;

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

public class demo01 {

    public static void main(String[] args) {
        method03();
    }public static void method03(){
        Collection col = new ArrayList();
        col.add("123");
        col.add(123);
        Iterator  it = col.iterator();
        while(it.hasNext()){
            if(it.next() instanceof String){   //这里的两个it.next()不是一个
                String  s = (String)it.next();
                System.out.println(s);
            }
        }
    }
}

会出现以下异常:

(2)添加泛型避免异常;在编译时期出现编译失败;

与上面对比:

package com.oracle.demo01;

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

public class demo01 {

    public static void main(String[] args) {
        Collection<String> col = new ArrayList<String>();
        col.add("abc");
        col.add("def");
        Iterator<String> it = col.iterator();
        while(it.hasNext()){
            System.out.println(it.next());
        }
        method03();
    } public static void method03(){
        Collection col = new ArrayList();
        col.add("123");
        col.add(123);
        Iterator  it = col.iterator();
        while(it.hasNext()){
            if(it.next() instanceof String){
                String  s = (String)it.next();
                System.out.println(s);
            }
        }
    }
}

效果如下:

当添加元素时:The method add(String) in the type Collection<String> is not applicable for the arguments (int)

 


(3)并发修改异常:ConcurrentModificationException;对集合进行增删操作;
迭代器不知道集合中的变化,容易发生调用的不确定性,[ListIterator了解即可]

public class ListIteratorDemo {

    public static void main(String[] args) {
        List list = new ArrayList();

        list.add("one");
        list.add("two");
        list.add("three");
        list.add("five");

        /*for(Iterator it = list.iterator(); it.hasNext();){
            Object obj = it.next();
            if(obj.equals("five")){

                 在迭代过程中,如果使用了集合的方法进行增删改查操作,那么迭代器会抛出异常.
                 原因是,迭代器不知道集合中的变化,容易发生调用的不确定性.
                 解决办法: 在迭代时,不要使用集合的方法进行操作元素.
                          可以使用迭代器的子接口ListIterator<E>中的方法就可以.
                          里面有很多操作元素的方法.而且可以正向迭代,反向迭代.
                 * 
                //list.add("four");    
                // 异常 ConcurrentModificationException
            }
            System.out.println(obj);
        }*/

        //用ListIterator重新解决问题
        for(ListIterator it = list.listIterator(); it.hasNext();){
            Object obj = it.next();
            if("three".equals(obj)){
                it.add("four");    //[one, two, three, four, five]
//                it.set("3");    //[one, two, 3, five]
                //对比输出结果
            }
        }
        System.out.println(list);
    }
}

 

2、增强for循环:
(1)for(元素的数据类型 变量:Collection集合or数组){ };

package com.oracle.demo01;

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

public class demo03 {

    public static void main(String[] args) {
        Collection<demo02> col = new ArrayList<demo02>();
        col.add(new demo02("熊大",12));
        col.add(new demo02("熊二",13));
        //普通for
        ArrayList<demo02> list = (ArrayList<demo02>)col;
        for(int i = 0;i < list.size();i++){
            System.out.println(list.get(i));
        }
        //增强for遍历集合
        for(demo02 p:col){
            System.out.println(p);
        }
    }

}

效果都是一样的:

 


(2)无法进行1-100求和等操作;因为目标只能是数组和集合
(3)相当于一个迭代器:不要进行增删操作;
3、泛型:
(1)修饰符 class 类名<代表泛型的变量E> { }

举个例子:

package com.oracle.demo02;

public class demo04 <E>{

    public static void main(String[] args) {
         demo04<String> s = new demo04<String>();

    }

}

(2)将运行时期的ClassCastException,转移到了编译时期变成了编译失败。
避免了类型强转的麻烦;

(3)泛型和注释不进class文件;
4、List接口[有序、可重复]
(1)并发修改异常解决办法:在迭代时,不要使用集合的方法操作元素

package com.oracle.demo02;

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

public class demo01 {
    public static void main(String[] args) {
         List<String> list = new ArrayList<String>();
         list.add("abc");
         list.add("def");
         //Iterator 迭代器遍历
         Iterator<String> it = list.iterator();
         //找到“def”这个元素时,在“def”这个位置添加一个元素叫做ghi
         while(it.hasNext()){
             if(it.next().equals("def")){
                 list.add("ghi");
             }
         }
    }
}

效果如下:

 


(2)List集合存储数据的结构:
堆栈:先进后出;压栈;栈的入口、出口都是栈的顶端位置;弹栈;
队列:先进先出;队列的入口、出口各占一侧;
数组:查找元素快;增删元素慢;
链表:多个节点之间,通过地址链接;查找元素慢;增删元素快;

 


(3)ArrayList集合数据存储的结构是数组结构:查找元素快;增删元素慢
LinkedList集合数据存储的结构是链表结构:查找元素慢;增删元素快;
(4)Vector集合[认识即可]:已被ArrayList替代;
5、set接口[无序、不重复]:
(1)HashSet集合:采用哈希表结构存储数据,保证元素唯一性的方式依赖于:hashCode()与equals()方法
在给哈希表中存放对象时,会调用对象的hashCode方法,算出对象在表中的存放位置,这里需要注意,
如果两个对象hashCode方法算出结果一样,这样现象称为哈希冲突,这时会调用对象的equals方法,
比较这两个对象是不是同一个对象,如果equals方法返回的是true,那么就不会把第二个对象存放在哈希表中,
如果返回的是false,就会把这个值存放在哈希表中;
(2)HashSet集合存储API类时:已经重写了hashCode方法和equals方法,如String类、Integer类等;
HashSet集合存储自定义类时:需要重写hashCode方法和equals方法,来确保HashSet集合中的对象唯一;

举个例子:

建立一个  demo02类:

package com.oracle.demo01;

public class demo02 {
       private String name;
       private Integer age;
    public demo02() {
        super();
    }
    public demo02(String name, Integer age) {
        super();
        this.name = name;
        this.age = age;
    }
    public String toString() {
        return "demo01 [name=" + name + ", age=" + age + "]";
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public Integer getAge() {
        return age;
    }
    public void setAge(Integer age) {
        this.age = age;
    }
    
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((age == null) ? 0 : age.hashCode());
        result = prime * result + ((name == null) ? 0 : name.hashCode());
        return result;
    }
    
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        demo02 other = (demo02) obj;
        if (age == null) {
            if (other.age != null)
                return false;
        } else if (!age.equals(other.age))
            return false;
        if (name == null) {
            if (other.name != null)
                return false;
        } else if (!name.equals(other.name))
            return false;
        return true;
    }

    
}

此时再进行存数据时:

package com.oracle.demo01;

import java.util.HashSet;

public class hash {

    public static void main(String[] args) {
        HashSet<demo02> set = new HashSet<demo02>();
           set.add(new  demo02("a",18));
        set.add(new  demo02("b",19));
        set.add(new  demo02("c",20));
        set.add(new  demo02("a",18));
        for(demo02 p:set){
            System.out.println(p);
        }
    }

}

效果如下:

 

以上是关于Java的Iterator迭代器补充,增强for循环,泛型,List接口,set接口的主要内容,如果未能解决你的问题,请参考以下文章

java之Iterator迭代器 增强for循环

迭代器和增强for循环

java基础(18):集合Iterator迭代器增强for循环泛型

Iterator迭代器与增强for循环

Java基础知识回顾-19(Collect接口,Iterator迭代器与增强for循环)

Java 集合框架迭代器(Iterator)