java集合Collection介绍和iterator方法

集合类的继承关系和基本方法

数组和集合

数组的长度是固定,改变数组长度的方式是创建新的数组,将旧数组复制到新的数组里.

集合类能存储任意长度的对象,集合的长度可以随着元素的增加而增加,随元素减少而减少

数组和集合区别

数组既可以存储基本数据类型(存储值),又可以存储引用数据类型(可以不同种对象,存储地址值),数组长度是固定的,不能自动增长

集合只能存储引用数据类型(可以不同种对象,地址值),如果存储基本数据类型时,会自动装箱变成相应的包装类,集合的长度的是可变的,可以根据元素的增加而自动增长

集合是一个接口,它的继承子类和实现类主要有:(图片只绘制了主要框架,具体继承和实现的类没标出)

集合是接口,没有构造方法,集合的初始化可以采用多态的形式,集合引用指向子类对象

集合接口的主要方法:

boolean add(E e)向集合中添加一个元素,如果E是集合类,就会把集合e当作元素添加到原集合中

boolean addAll(Collection c)向集合中添加一个集合的元素,添加了c中的每个元素
boolean remove(Object o)从集合中移除指定元素,

boolean removeAll(Collection c)从集合中移除所有(即存在于原集合又存在于集合c中的)元素
void clear()清空集合
boolean contains(Object o)集合中是否包含某个元素(比较的是该元素与整个集合的所有元素的地址,如果元素的类没有重写equals方法,则返回不正确的值,所以调用该方法要确保已经重写equals方法)

boolean containsAll(Collection c)集合中是否包含了指定集合的所有元素,
boolean isEmpty() 集合是否不包含元素
int size() 返回集合中元素的个数

Object toArrays()返回一个Object类型数组

Iterator<E> iterator()返回一个迭代器对象,这个后面说.

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

public class CollectionTest02 {
	public static void main(String[] args) {
		Collection c1 = new ArrayList();
		Collection c2 = new ArrayList();
		c1.add("a");// 向集合中添加元素
		c1.add("b");
		c1.add("c");
		c1.add("d");
		c1.add("e");
		c1.add("f");
		c2.add("a");
		c2.add("b");
		c2.add("c");
		c2.add("d");
		c2.add("d");
		c2.add("h");
		System.out.println(c1);// c1=["a","b","c","d","e","f"]
		System.out.println(c2);// c2=["a","b","c","d","h"]
		// contain
		System.out.println(c1.contains("a"));// true
		// containsAll
		System.out.println(c1.containsAll(c2));// false
		// remove
		c1.remove("a");// c1=["b","c","d","e","f"]
		// remove集合中不存在的元素值时,返回false
		System.out.println(c1.remove("g"));// false
		System.out.println(c1);
		// removeAll
		c1.removeAll(c2);// c1=[e,f]
		System.out.println(c1);
		// clear
		c2.clear();// c2=[]
		System.out.println(c2.isEmpty());// true
		System.out.println(c1.size());// 2
		// c2重新添加一些元素
		c2.add("c");
		c2.add("d");
		c2.add("d");
		c2.add("h");
		c1.add(c2);
		System.out.println(c1);
		c1.addAll(c2);
		System.out.println(c1);
	}
}
out:
a, b, c, d, e, f]
[a, b, c, d, d, h]
true
false
false
[b, c, d, e, f]
[e, f]
true
2
[e, f, [c, d, d, h]]
[e, f, [c, d, d, h], c, d, d, h]

添加自己定义的对象时

对于打印对对象,Collection接口的子类AbstractedCollection中重写了toString方法,所以打印集合对象不会打印集合对象的地址,而是每个对象元素,但是如果集合中的元素没有重写toString方法,那么打印出来的对象元素还是每个元素的地址,所以,集合中的元素要重写toString方法,有些类已经重写了,比如String类

equals方法,同样对于集合中的元素,如果该元素(是一个对象)没有重写equals方法,那么在集合中的操作是操作该对象引用的堆内存地址,remove方法删除不了该对象,contains方法返回的值也不正确,所以要重写equals方法

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

import students.Student;

public class CollectionTest03 {
	public static void main(String[] args) {
		Collection c1 = new ArrayList();
		c1.add(new Student(12, "张"));
		c1.add(new Student(13, "李"));
		c1.add(new Student(14, "赵"));
		c1.add(new Student(15, "刘"));
		// 如果没有重写equals方法,删除的只是s1的地址,s1的地址不在集合中,所以还是原来的集合
		// contains比较的也是地址,那么返回false
		// 重写equals方法后,才会比较引用的内容,remove和contains方法才生效
		Student s1 = new Student(13, "李");
		System.out.println(c1.contains(s1));
		c1.remove(s1);
		System.out.println(c1);
		// toArray方法,返回Object类型数组
		Object[] objs = c1.toArray();
		for (int i = 0; i < objs.length; i++) {
			System.out.println(objs[i]);
		}
		// 清除c1集合的全部元素
		c1.clear();
		System.out.println(c1.isEmpty());

	}
}
out:
true
[Student [age=12, name=张], Student [age=14, name=赵], Student [age=15, name=刘]]
Student [age=12, name=张]
Student [age=14, name=赵]
Student [age=15, name=刘]
true

注:ArrayList和其父类AbstractList都实现了List<>接口,效果上没什么特别用途,仅仅是为了让人阅读源码时知道子类实现了该核心接口。就像很多人都知道 ArrayList实现了List接口就够了,而不需要知道它继承AbstractList的相关细节。

Iterator<E> iterator()  获取Iterator接口实例

iterator是集合中的一个重写的方法,Collection继承了Iterable,Iterable接口中定义了返回Iterator实例的方法iterator,iterator实例可以遍历集合

jdk11    Iterable中iterator方法的定义:

Iterator<E> iterator();//只提供一个抽象方法,需要子类实现

Collection的子类下面ArrayList中实现的源码为:

public Iterator<E> iterator() {
        return new Itr();
    }
 private class ListItr extends Itr implements ListIterator<E> {
        ListItr(int index) {
            super();
            cursor = index;
        }

        public boolean hasPrevious() {
            return cursor != 0;
        }

        public int nextIndex() {
            return cursor;
        }

        public int previousIndex() {
            return cursor - 1;
        }

        @SuppressWarnings("unchecked")
        public E previous() {
            checkForComodification();
            int i = cursor - 1;
            if (i < 0)
                throw new NoSuchElementException();
            Object[] elementData = ArrayList.this.elementData;
            if (i >= elementData.length)
                throw new ConcurrentModificationException();
            cursor = i;
            return (E) elementData[lastRet = i];
        }

        public void set(E e) {
            if (lastRet < 0)
                throw new IllegalStateException();
            checkForComodification();

            try {
                ArrayList.this.set(lastRet, e);
            } catch (IndexOutOfBoundsException ex) {
                throw new ConcurrentModificationException();
            }
        }

        public void add(E e) {
            checkForComodification();

            try {
                int i = cursor;
                ArrayList.this.add(i, e);
                cursor = i + 1;
                lastRet = -1;
                expectedModCount = modCount;
            } catch (IndexOutOfBoundsException ex) {
                throw new ConcurrentModificationException();
            }
        }
    }

Iterator和Iterable在集合中的应用

Iterable是Collection的父接口,Iterator是单独的接口,但是Iterable中有一个方法可以返回Iterator接口的实例

然后在Collection的子类中也有实现Iterator接口及其子接口的内部类,调用对应的方法可以返回Iterator对象

总结:所有的Collection子类会实现Iteratable接口以实现foreach功能,Iteratable接口的实现又依赖于实现了Iterator的内部类(参照LinkedListlistIterator()descendingIterator()的JDK源码)。有的容器类会有多个实现Iterator接口的内部类,通过返回不同的迭代器实现不同的迭代方式。

大致的Iterator,Iterable和Collection关系如下图,但是Collection子类中有多个都定义了实现Iterator接口及其子接口的内部类,

Iterator接口的方法

boolean hasNext() 定义一个指针,返回当前指针指向的索引处是否还有元素,如果有就返回true,此方法不会移动指针

E next()该方法返回当前指针下的元素,同时将指针后移,当该指针移动到最后面时,再调用hasNext返回的就是false,再调用next方法会报出异常java.util.NoSuchElementException

 利用iterator方法获取Iterator实例来遍历Collection例子

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

import students.Student;

public class IteratorTest {
	public static void main(String[] args) {
		ArrayList c1 = new ArrayList();
		c1.add(new Student(12, "张"));
		c1.add(new Student(13, "李"));
		c1.add(new Student(14, "赵"));
		c1.add(new Student(15, "刘"));
		//for循环遍历集合对象,打印对象
		for (Iterator iterator = c1.iterator(); iterator.hasNext();) {
			System.out.println(iterator.next());
		}
		Iterator it = c1.iterator();
		// while循环直接打印对象
		while (it.hasNext()) {
			System.out.println(it.next());
		}
		// while循环获取元素后,向下转型,调用元素的get方法获取对象属性
		while (it.hasNext()) {
			Student s = (Student) it.next();
			System.out.println(s.getName() + " " + s.getAge());
		}

	}
}
out:
Student [age=12, name=张]
Student [age=13, name=李]
Student [age=14, name=赵]
Student [age=15, name=刘]
Student [age=12, name=张]
Student [age=13, name=李]
Student [age=14, name=赵]
Student [age=15, name=刘]

参考:https://www.aliyun.com/jiaocheng/773540.html

        http://www.monkey1024.com/javase/528

https://www.jianshu.com/p/cf82ab7e51ef

  Chinese (Simplified)English Chinese (Simplified)English

Text-to-speech function is limited to 200 characters

  Options : History : Feedback : Donate Close

猜你喜欢

转载自blog.csdn.net/sinat_41132860/article/details/84069142