Java集合框架(1)

    集合是存储对象最常用的一种方式,数组虽然也可以存储对象,但长度是固定的;集合长度是可变的。数据中可以存储基本数据类型,集合只能存储对象。集合只用于存储对象,集合长度是可变的,集合可以存储不同类型的对象。(其实,集合中能够存储的都是对象的引用或地址。)为什么会出现集合类呢?数据多了就封装成对象,对象多了也是需要存储的,然后集合类就出现了。集合框架:

    Collection(根节点)

       |--List:元素是有序的,元素是可以重复。因为该集合体系有索引。

    |--ArrayList:底层的数据结构使用的是数组结构。特点:查询,修改操作简单,插入,删除操作复杂

    |--LinkedList:底层的数据结构使用的是链表结构。特点:插入,删除操作简单,查询,修改操作复杂

    |--Vector:底层是数组数据结构,Vector是同步的,ArrayList是不同步的。被ArrayList替代了。

       |--Set:元素是无序的,元素不可以重复。

    首先看一下Collection类,它里面有个add(Object o)方法,它的参数是Object,因此可以接受任何对象。除了add()以外还有其他一些方法,这里就省略不讲,一般容器都具备增删改查的特性。我们要看一下迭代器的概念。

    什么是迭代器?其实就是集合的元素的取出方式。迭代器的特点:因为每个容器的底层的数据结构不一样,所以它们存取动作的实现方式可能就不一样。对于取出这个动作不足以用一个函数来描述,跟存(add()方法)不一样,它需要多个功能来体现。就把多个功能封装成一个对象。这个对象在容器内部。其实就是把取出方式定义在集合的内部,这样取出方式就可以直接访问集合内部的元素。即这个取出方式就被定义成了内部类。而每一个容器的数据结构不同,所以取出的动作细节也不一样,但是都有共性内容:判断和取出,那么可以将写共性抽取。那么这些内部类都符合一个规则。该规则是Iterator。如何获取集合的迭代对象呢?通过一个对外提供的方法:iterator()

 

//下面可以用更简洁的foreach替代
for (Iterator it = 集合.iterator(); it.hasNext(); ) {
       // do something with it
}

 

    接下来看一下Collection的子接口—— List: 它有一些特有的方法,凡是可以操作下标的方法都是该体系特有的方法。

 

增:add(index, element); addAll(int index, Collection collection);

删:remove(index);

改:set(index, element);

查:get(index); subList(fromIndex, toIndex); listIterator();

还可以通过indexOf()获取对象在集合中的位置。

ListIterator<E> extends Iterator<E>

List集合特有的迭代器。ListIterator是Iterator的子接口。在迭代时,不可以通过集合对象的方法操作集合中的元素。因为会发生ConcurrentModificationException异常。所以在迭代时,只能用迭代器的方法操作元素,可是Iterator方法是有限的(hasNext(),Next(),remove()),只能对元素进行判断,取出,删除的操作,如果想要其他的操作如添加,修改等,就需要使用其子接口,ListIterator。该接口只能同List集合的listIterator()方法获取。

List集合判断元素是否相同(例如判断集合中是否包含某个元素,又或者要移除集合中的某个元素,要先判断是否有该函数),依据的是元素的equals()方法,在本文最后面有个例程可以证明。

    LinkedList的特有方法:

addFirst(); addLast();

getFirst(); getLast(); 获取元素,但不删除。如果集合中没有元素,会出现NoSuchElementException

removeFirst();removeLast();获取元素,但是元素被删除。如果集合中没有元素,会出现NoSuchElementException

在JDK 1.6出现了替代方法:

offerFirst();offerLast();

peekFirst();peekLast();获取元素,但不删除。如果集合中没有元素,会返回null

pollFirst();pollLast();获取元素,但是元素被删除。如果集合中没有元素,会返回null

    在List中还有就是Vector:Vector是比较浪费空间,枚举(Enumeration接口,它的功能和Iterator的功能是重复的)是Vector特有的取出方式。Vector已经被ArrayList替代了,前面也讲到了。

 

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

class Person {
	private String name;
	private int age;
	
	public Person(String name, int age) {
		this.name = name;
		this.age = age;
	}
	
	public String getName() {
		return name;
	}
	
	public int getAge() {
		return age;
	}
	
	public String toString() {
		return "name: " + getName() + " age: " + getAge();
	}
	//同名,同年龄就判断它们相同,如果下面这个方法不重写的话,下面代码中的remove()和contains()方法就不能起作用了。
	public boolean equals(Object obj) {
		if (this == obj) return true;
		if (obj == null) return false;
		if (this.getClass() != obj.getClass()) return false;
		Person that = (Person) obj;
		return (this.age == that.age) && (this.name.equals(that.name));			
	}
}
public class ArrayListDemo {
    public static void main(String[] args) {
    	ArrayList<Person>  test = new ArrayList<Person>();
    	for (int i=0; i<5; i++)
    		test.add(new Person("name" + i, i));
    	for (int i=0; i<5; i++)
        	test.add(new Person("name" + i, i));
    	System.out.println("remove(): " + test.remove(new Person("name1", 1))); // 这里的remove()会调用集合元素中的equals()方法来判断
    	System.out.println("消除重复前:");
    	for (Person p: test)
    	System.out.println(p);
    	test = singleElement(test);
    	
    	System.out.println("消除重复后:");
    	for (Person p: test) {
    		System.out.println(p);
    	}
	}
	
	public static <E> ArrayList<E> singleElement(ArrayList<E> arrayList) {
	    ArrayList<E> temp = new ArrayList<E>();
		for (Iterator it = arrayList.iterator(); it.hasNext(); ) {
           // 在迭代时循环中next()调用一次,就要hasNext()判断一次
		   E element = (E) it.next();
			if (!temp.contains(element)) { // 调用contains()会调用集合元素的equals()方法,remove()方法也是一样调用了集合元素的equals()方法
			    temp.add(element);
			}
		}
		/*
		for (E element: arrayList) {
		    if (!temp.contains(element)) {
			    temp.add(element);
			}
		}
		*/
		return temp;
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值