五、集合——2-Collection接口和Iterator接口

2-Collection接口和Iterator接口

1.概述

(1)Collection接口是Set、Queue和List接口的父接口;

(2)Collection中定义了如下常用方法操作Collection集合中的元素

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

//Collection为List、Set、Queue接口的父接口
//即在Collection中定义的方法适用于List、Set、Queue
//以List为例
public class CollectionTest {
    public static void main(String[] args) {
        /*
         * Collection接口中的常用方法
         */
        //创建List集合
        Collection listA = new ArrayList();
        Collection listB = new ArrayList();
        //添加元素
     //所有的Collection接口的实现类都重写了toString()方法
listA.add("AA"); listA.add("AB"); listA.add("AC"); listB.add("BA"); listB.add("BB"); listB.add("BC"); System.out.println(listA); System.out.println(listB); //把集合listB中的元素全部添加(复制)到listA中 listA.addAll(listB); System.out.println(listA); System.out.println(listB); //清除集合中的所有元素 Collection listC = new ArrayList(); listC.add("CA"); listC.add("CB"); listC.add("CC"); System.out.println(listC); listC.clear(); System.out.println(listC); //返回集合中是否包含指定元素 System.out.println("listA集合中是否包含字符串AA:"+listA.contains("AA")); //listA集合中是否包含listB集合 System.out.println("listA集合是否包含listB集合:"+listA.containsAll(listB)); //判断集合是否为空,即集合长度为0 System.out.println("listC集合长度是否为0:"+listC.isEmpty()); //获取Iterator对象(此对象用于遍历集合) Iterator iterator = listA.iterator(); //删除集合中的指定元素 listA.remove("AA"); System.out.println(listA); //从listA中删除listB所包含的所有元素 listA.removeAll(listB); System.out.println(listA); listA.addAll(listB); //把listA变为listA和listB的交集 listA.retainAll(listB); System.out.println(listA); //获取集合元素个数 System.out.println("listA中的元素个数为:"+listA.size()); //把集合转变为与其元素对应的数组 Object[] objs = listA.toArray(); System.out.println(objs); for(Object obj:objs){ System.out.println(obj); } } }

 

2.使用Lambda表达式遍历集合

(1)Iterable接口是Collection接口的父接口,在Iterable接口中提供了forEach(Consumer action)方法,可以使用该方法遍历Collection集合的元素,Consumer接口是一个函数式接口,所以可以使用Lambda表达式遍历集合。(函数式接口:接口中的方法唯一);

(2)Consumer接口中唯一的方法为accept(T t);

(3)使用Lambda表达式遍历Collection集合:

import java.util.ArrayList;
import java.util.Collection;
import java.util.function.Consumer;

//Iterable是Collection接口的父接口
//在Iterable接口中定义了forEach(Consumer action)方法用来遍历集合
//Consumer接口是一个函数式接口,所以可以使用Lambda表达式遍历集合元素
public class ForEachTest {
    public static void main(String[] args) {
        //创建Collection集合
        Collection list = new ArrayList();
        //添加元素
        list.add("a");
        list.add("b");
        list.add("c");
        //调用forEach()方法,使用Lambda表达式遍历集合元素
        list.forEach(obj->System.out.println(obj));
        //使用实现接口的方式使用forEach()方法
        list.forEach(new Consumer(){
            @Override
            public void accept(Object obj) {
                // TODO Auto-generated method stub
                System.out.println(obj);
            }});
    }
}

 

 

 

3.使用Iterator遍历集合元素

(1)Iterator用于遍历Collection集合元素,Iterator对象也被成为迭代器;

(2)Iterator接口中定义的四个方法:

  ①boolean hasNext():被迭代的集合未被遍历完,返回true;

  ②Object next():返回集合里的下一个元素;

  ③void remove():删除集合里上一次next方法返回的元素;

  ④void forEachRemaining(Consumer action):可以通过该方法使用Lambda表达式遍历集合元素;

(3)Iterator的使用:

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

public class IteratorTest {
    public static void main(String[] args) {
        //Iterator用于遍历Collection集合
        
        //创建Collection集合
        Collection list = new ArrayList();
        list.add("a");
        list.add("b");
        list.add("c");
        //创建Iterator对象
        Iterator iterator = list.iterator();
        //遍历集合
        while(iterator.hasNext()){
            String str = (String)iterator.next();
            if(str.equals("a")){
                //从集合中删除上一次next()的元素
                iterator.remove();
            }
            //注意:在Iterator中对变量赋值,不会修改集合中的元素
            str = "d";
        }
        System.out.println(list);
    }
}

 

(4)注意:

  ①在Iterator中迭代的元素并不是集合元素的本身,所以在对迭代变量修改时并不能修改集合中对应的元素,只有通过Iterator的remove()方法才能删除上次next()方法返回的集合元素,并对集合产生影响;

  ②除了使用Iterator的remove()方法外,不要在迭代过程中对集合进行修改,否则会出现异常。

 

4.使用Lambda表达式遍历Iterator

(1)类似于Iterable接口中的forEach(Consumer action)方法,也可通过Iterator的forEachRemaining(Consumer action)方法使用Lambda表达式遍历Iterator。

(2)注意,其遍历的是Iterator不是集合本身:

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

public class ForEachRemainingTest {
    public static void main(String[] args) {
        Collection list = new ArrayList();
        list.add("a");
        list.add("b");
        list.add("c");
        Iterator iterator = list.iterator();
        //使用Iterator的forEachRemaining()方法,遍历Iterator
        iterator.forEachRemaining(obj->System.out.println(obj));
    }
}

 

 

 

5.foreach遍历集合元素

(1)类似于使用foreach遍历数组,需要注意的是,使用foreach遍历时,foreach的迭代变量也并非集合元素本身,修改迭代变量的值对集合没有影响,同样,类似于Iterator,不可以在循环中修改集合,否则会出现异常。

(2)foreach遍历集合元素的使用:

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

public class MyForeachTest {
    public static void main(String[] args) {
        Collection list = new ArrayList();
        list.add("a");
        list.add("b");
        list.add("c");
        for(Object obj:list){
            System.out.println(obj);
        }
    }
}

 

6.Predicate

(1)使用Predicate过滤集合:

  在Collection接口中有一个removeIf(Predicate filter)方法,该方法会批量删除符合filter的所有元素。该方法的参数Predicate接口是一个函数式接口(方法test()唯一),所以也可以使用Lambda表达式使用此方法;

 

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.function.Predicate;

//使用Collection的removeIf(Predicate filter)方法过滤集合
public class PredicateTestA {
    public static void main(String[] args) {
        Collection list = new ArrayList();
        list.add("aab");
        list.add("aac");
        list.add("abc");
        list.add("bcd");
        //使用removeIf(Predicate filter)方法删除带有aa字符串的字符串
        list.removeIf(ele->((String)ele).contains("aa"));
        System.out.println(list);
        Collection set = new HashSet();
        set.add("aab");
        set.add("aac");
        set.add("abc");
        set.add("cbd");
        //不使用Lambda表达式,直接使用实现Predicate接口的方式,过滤元素
        set.removeIf(new Predicate(){

            @Override
            public boolean test(Object t) {
                // TODO Auto-generated method stub
                if(((String)t).contains("aa")){
                    return true;    //返回值为true的将被过滤掉
                }else{    
                    return false;
                }
            }});
        System.out.println(set);
    }
}

 

(2)使用Predicate简化集合的运算:

  使用Predicate可以简化一些对集合较为复杂的运算需求:

  实现以下需求,有Student对象若干,其属性sex为“女”的统计数量;属性sex为男的统计数量;统计属性score>60的数量,代码如下:

Student类:

public class Student {
    private String name;
    private String sex;
    private int score;
    public Student(){
        
    }
    public Student(String name,String sex,int score){
        this.name = name;
        this.sex = sex;
        this.score = score;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getSex() {
        return sex;
    }
    public void setSex(String sex) {
        this.sex = sex;
    }
    public int getScore() {
        return score;
    }
    public void setScore(int score) {
        this.score = score;
    }
}

 

 

 

PredicateUtil类:

import java.util.Collection;
import java.util.function.Predicate;

public class PredicateUtil {
    public static int count(Collection stus,Predicate p){
        int count = 0;
        for(Object stu:stus){
            if(p.test(stu)){
                count++;
            }
        }
        return count;
    }
}

 

 

 

Test类:

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

public class Test {
    public static void main(String[] args) {
        Student stuA = new Student("A","男",65);
        Student stuB = new Student("B","女",70);
        Student stuC = new Student("C","男",80);
        Student stuD = new Student("D","男",51);
        Student stuE = new Student("E","女",50);
        Student stuF = new Student("F","女",65);
        Student stuG = new Student("G","男",66);
        //创建集合存放Student对象
        Collection stus = new ArrayList();
        stus.add(stuA);
        stus.add(stuB);
        stus.add(stuC);
        stus.add(stuD);
        stus.add(stuE);
        stus.add(stuF);
        stus.add(stuG);
        //统计
        //sex属性为男的数量
        int nan = PredicateUtil.count(stus, stu->((Student)stu).getSex().equals("男"));
        //sex属性为女的数量
        int nv = PredicateUtil.count(stus, stu->((Student)stu).getSex().equals("男"));;
        //score>60的数量
        int score = PredicateUtil.count(stus, stu->((Student)stu).getScore()>60);
        //输出
        System.out.println(nan);
        System.out.println(nv);
        System.out.println(score);
    }
}

 

 

 

 

7.Stream

(1)Stream、IntStream、LongStream、DoubleStream等流式API代表多个支持串行和并行聚集操作的元素。在这几个接口中,Stream是一个通用的流接口,其余的分别代表元素类型为int、long和double;

(2)独立使用Stream的步骤如下:

  ①使用Stream的builder()类方法创建该Stream对应的Builder;

  ②重复调用Builder的add()方法向该流中添加多个元素;

  ③调用Builder的buil()方法获取对应的Stream;

  ④调用Stream的聚集方法;

  对于大多数的聚集方法,这些方法只能执行一次;

(3)Stream中的聚集方法

  1)中间方法:允许流保持打开状态,并允许直接调用后续方法;

  2)末端方法:对流的最终操作,当执行过末端方法后,该流将变为不可用的状态并被消耗;

  这些聚集方法,都是用于对Stream中的元素进行操作,或者操作Stream集合。

(4)Collection接口提供了一个stream()方法,该方法可以返回此集合对应的流,在获得对应的流之后就可以通过流式API操作集合元素。使用Stream直接对集合中所有元素进行批量操作:

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

public class Test2 {
    public static void main(String[] args) {
        //创建由Student构成的集合
        Student stuA = new Student("A","男",65);
        Student stuB = new Student("B","女",70);
        Student stuC = new Student("C","男",80);
        Student stuD = new Student("D","男",51);
        Student stuE = new Student("E","女",50);
        Student stuF = new Student("F","女",65);
        Student stuG = new Student("G","男",66);
        //创建集合存放Student对象
        Collection stus = new ArrayList();
        stus.add(stuA);
        stus.add(stuB);
        stus.add(stuC);
        stus.add(stuD);
        stus.add(stuE);
        stus.add(stuF);
        stus.add(stuG);
        //统计sex为男的数量
        int nan = (int) stus.stream().filter(stu->((Student)stu).getSex().equals("男")).count();
        System.out.println(nan);
        //统计sex为女的数量
        int nv = (int) stus.stream().filter(stu->((Student)stu).getSex().equals("女")).count();
        System.out.println(nv);
        //统计score>60的数量
        int score = (int) stus.stream().filter(stu->((Student)stu).getScore()>60).count();;
        System.out.println(score);
    }
}

 

 

 

posted @ 2017-08-02 19:55  丶theDawn  阅读(197)  评论(0编辑  收藏  举报