欢迎访问悦橙教程(wld5.com),关注java教程。悦橙教程  java问答|  每日更新
页面导航 : > > 文章正文

黑马程序员 集合学习笔记三,黑马程序员学习笔记

来源: javaer 分享于  点击 36165 次 点评:265

黑马程序员 集合学习笔记三,黑马程序员学习笔记


----------android培训、java培训、java学习型技术博客、期待与您交流!----------

Collection体系:某个线程在Collection 上进行迭代时,通常不允许另一个线性修改该 Collection。通常在这些情况下,迭代的结果是不确定的。如果检测到这种行为会抛出异常

 

Iterator迭代器抛出异常举例如下:

public static void main(String[] args) {
        List<String>list = new ArrayList<String>();
       list.add("a000");
       list.add("a001");
       list.add("a002");
       list.add("a003");
        /*此处既想进行迭代又想进行添加元素,所以迭代的结果是不确定的,抛出java.util.ConcurrentModificationException异常*/
    
       Iterator<String> it =list.iterator();
       while(it.hasNext()){
           if(it.next().equals("a000")){
              list.add("a005");
           }
       }
    }


 

解决办法:只要在迭代过程中不通过集合本身就行,而Iterator提供的方法有限,考虑到Iterator的子接口ListIterator,其提供了更为实用的方法,代码修改如下:

public static void main(String[] args) {
        List<String> list = new ArrayList<String>();
        list.add("a000");
        list.add("a001");
        list.add("a002");
        list.add("a003");
       
        ListIterator<String> lit = list.listIterator();
        System.out.println(list);
        while(lit.hasNext()){
            if(lit.next().equals("a000")){
                lit.add("a005");//迭代器对集合进行操作,而不是集合自身
            }
        }
       
        System.out.println(list);
    }


运行结果(注意所添加元素的位置):

[a000, a001, a002, a003]

[a000, a005, a001, a002, a003]

 

特别说明:ListIterator迭代器只适合在迭代List集合时对集合元素进行增删改查的操作

 

Collections:此类完全由在 collection 上进行操作或返回 collection 的静态方法组成,其提供对Collection集合的多种操作


Collection集合接口

public interface Collection<E> extends Iterable<E> {
/** Query Operations **/
	// Returns the number of elements in this collection.
	int size();
	// Returns “true” if this collection contains no elements.
	boolean isEmpty();
	// Returns <tt>true</tt> if this collection contains the specified element.
	boolean contains(Object o);
	// Returns an iterator over the elements in this collection.
	Iterator<E> iterator();
	// Returns an array containing all of the elements in this collection.
	Object[] toArray();
	// Returns an array containing all of the elements in this collection;
	// the runtime type of the returned array is that of the specified array.
	<T> T[] toArray(T[] a);
/** Modification Operations **/
	// Ensures that this collection contains the specified element (optional
	// operation).  Returns <tt>true</tt> if this collection changed as a
	// result of the call.
	boolean add(E e);
	// Removes a single instance of the specified element from this collection。
	boolean remove(Object o);
/** Bulk Operations 组操作 **/
	// Returns <tt>true</tt> if this collection contains all of the elements in the specified collection.允许您查找当前集合是否包含了另一个集合的所有元素,即另一个集合是否是当前集合的子集。
	boolean containsAll(Collection<?> c);
	// Adds all of the elements in the specified collection to this collection(optional operation).
	boolean addAll(Collection<? extends E> c);
	// Removes all of this collection's elements that are also contained in the specified collection(optional operation).public abstract Iterator<E> iterator();

    public abstract int size();
	boolean removeAll(Collection<?> c);
	// Retains(保持,记住) only the elements in this collection that are contained in the specified collection(optional operation).从当前集合中除去不属于另一个集合的
素,即交。
	boolean retainAll(Collection<?> c);
	// Removes all of the elements from this collection(optional operation).
	void clear();
/** Comparison and hashing **/
	// Compares the specified object with this collection for equality.
	boolean equals(Object o);
	// Returns the hash code value for this collection.
	int hashCode();
}

Collection接口的iterator()方法返回一个Iterator。使用Iterator接口方法,您可以从头至尾遍历集合,并安全的从底层

Collection中除去元素:

remove()方法可由底层集合有选择的支持。当底层集合调用并支持该方法时,最近一次next()调用返回的元素就被除去。如下面代码:


Collection collection = ...;

Iterator iterator = collection.iterator();

while (iterator.hasNext()) {

	Object element = iterator.next();

	if (removalCheck(element)) {

		iterator.remove();

	}

}

AbstractCollection类(抽象类)


public abstract class AbstractCollection<E> implements Collection<E> {
	/** AbstractCollection 类提供具体“集合框架”类的基本功能。实现了大多数Collection接口中的方法。还有几个添加的方法。虽然您可以自行实现 Collection 接口的所有方法,但是,除
了iterator() 和 size() 方法在恰当的子类中实现以外,其它所有方法都由 AbstractCollection 类来提供实现。
	public abstract Iterator<E> iterator();
	public abstract int size(); 
	就剩下这两个方法没有提供实现,其他的都提供了实现代码 **/
}

我们看到Collection接口中有许多方法是可选的optionaloperation假如在运行过程中抛出UnsupportedOperationException异常,则操作失败,说明这个方法不被支持。


Set接口

Set接口继承Collection接口,没有添加新的方法。依赖添加对象方法add()中用到了equals()方法类确保唯一性。


publicinterfaceSet<E>extendsCollection<E> {

/**和Collection接口中的方法是一样一样的**/

}

集合框架”中提供了两个Set接口的实现类HashSet类和TreeSet类:

HashSet

考虑到效率,添加到HashSet的对象采用恰当的方式来实现来实现hashCode()方法,虽然大多数系统类都是覆盖了ObjecthashCode()方法;但是,当创建您自己的要添加到HashSet中的类时,别忘了覆盖ObjecthashCode()方法。

package java.util;
public class HashSet<E>
    extends AbstractSet<E>
    implements Set<E>, Cloneable, java.io.Serializable
{
	……
}

TreeSet

当你要从集合中以有序的方式抽取元素时,我们可以采用TreeSet实现会有好处。

为优化HashSet空间的使用,您可以调优初始容量和负载因子。TreeSet不包含调优选项,因为树总是平衡的,保证了插入、删

除、查询的性能为log(n)


package java.util;
public class TreeSet<E> extends AbstractSet<E>
    implements NavigableSet<E>, Cloneable, java.io.Serializable
{	
	……
	public HashSet(int initialCapacity, float loadFactor) {
        map = new HashMap<>(initialCapacity, loadFactor);
    }
	……
}

我们可以看到HashSet类和TreeSet类都实现了AbstrctSet类,下面就来看看AbstractSet类(抽象类)做了什么:

AbstractSet类(抽象类)

AbstractSet类覆盖了equals()hashCode()方法,以确保两个相等的集返回相同的散列码。若两个集大小相等且包含相同元素,则这两个集相等。按定义,集散列码是集中元素散列码的总和。因此,不论集的内部顺序如何,两个相等的集会报告相同的散列码。

package java.util;
public abstract class AbstractSet<E> extends AbstractCollection<E> implements Set<E> {
	protected AbstractSet() {
    }
	public boolean equals(Object o) {
        ……
    }
	public int hashCode() {
        ……
    }
	public boolean removeAll(Collection<?> c) {
        ……
    }

}

List接口

List接口继承了Collection接口,定义了一个允许重复项的的有序集合。还添加了一些方法:面向位置的操作;处理集合子类。

package java.util;
public interface List<E> extends Collection<E> {
	// 面向位置的操作
	void add(int index, Object element)

	boolean addAll(int index, Collection collection)

	Object get(int index)

	int indexOf(Object element)

	int lastIndexOf(Object element)

	Object remove(int index)

	Object set(int index, Object element)
	// 集合子集
	ListIterator listIterator()

	ListIterator listIterator(int startIndex)

	List subList(int fromIndex, int toIndex)
}

上面的代码中出现了ListIterator,来了解一下:

阅读ListIterator接口的定义源码发现ListIterator接口中多了几个方法:

booleanhasPrevious();

Eprevious();

intpreviousIndex();

由此可见,它是支持双向访问的。

LinkList/ArrayList

在“集合框架”中有两个List接口的实现类:ArrayList类和LinkList

ArrayList类:随即访问,而不必在除尾部外的任何位置插入或去除元素。

LinkList类:需要频繁的在列表中插入或去除元素,只需要顺序访问。添加了一些处理链表两端的方法,这样可以轻松的作为堆栈和队列。

AbstractList/AbstractSequentialList

在“集合框架”中有两个List接口的抽象实现类:AbstractList类和AbstractSequentialList


 

总结Collection的超级接口为Iterable。List、Set接口都继承Collection接口,Collection接口为 List、Set声明集合的基本操作方法,如获得迭代器,判断是否为空,是否包含某元素,保留或移除某些元素等。Map接口声明从关键字到值的映射<K,V>,而关键字或值的类型显然可以是List或Set的实现。通过学习、敲代码的实践以及查阅API,可以有这样一个形象的概念,Collection作为根节点(当然其上还有超级接口Iterable),与List、Set等子接口构成一颗树A;Map作为根,与其子接口构成另一棵树B,这种情况下,树A和树B构成一个森林。java代码敲得比较少,只是一种模糊的印象,所以到目前为止,我自己是这样理解的:层次上,Collection与Map属于同一层;功能上,可以将List、Map、Set看成是同一层,而在整个集合框架中, List、Map、Set是核心。

 

----------android培训、java培训、java学习型技术博客、期待与您交流!----------

 

相关文章

    暂无相关文章
相关栏目:

用户点评