java常见的4个类集接口collection,map,List,set

在类集之前,想保存数组的话就只能是使用对象数组。但是数组有长度的限制,而如果使用链表这种数据结构的话,又会比较麻烦。类集框架就是来解决上面的问题的,就是实现一个动态的数组,包装上数据结构,因此就会有类集的出现。类集接口有collection,map,List,set,Iterator,ListIterator,Enumeraation,

SortedMap,Queue,Map.Entry,在面试时就会经常遇到前面四个的问题。

一、Collection接口

Collection接口的定义如下

public interface Collection<E> extends Iterable<E>

从接口的定义可以看出来,这里是使用的泛型的定义,避免发生ClassCastException的异常。Collection接口是单值的存放最大父接口,可以向其中保存多个对象。继承于Iterable接口,Iterable接口已经是最大的接口了, 它主要是告诉我们它是可以进行迭代的。

public interface Iterable<T> {

Collection接口的所有方法如下:

/*2017/11/3:这两天在看码的时候才注意到一个小细节,那就是这个集合定义的许多方法都是返回的boolean类型,之前都没有注意到过。看下面的代码,其中的一个add方法,增加值的时候是这样增加的,先把这个list的容量加1,然后把数据才赋进去,前面两步没有问题的时候才会返回true,表面增加成功。源码中大部分的方法都是这样的。*/

public boolean add(E e) {
        ensureCapacityInternal(size + 1);  // Increments modCount!!
        elementData[size++] = e;
        return true;
    }

遍历Collection接口,不论Collection的实际类型如何,因为他是继承于Iterable接口,所以它都支持一个iterator()的方法,该方法返回一个迭代子,使用该迭代子即可逐一访问Collection中每一个元素:

Iterator it=collection.iterator();//获得一个迭代子

while(it.hasNext()){

Objectobj=it.next();//得到下一个元素

}

也可以使用foreach输出

for(元素类型t 元素变量x : 遍历对象obj){
     引用了x的java语句;
}
for (String x : list) { 
System.out.println(x); 
} 

Collection接口虽然是集合的最大接口,但是如果直接使用Colllection接口进行操作,则表示操作的含义不明确,因此会一般使用他的子接口。Collection的子接口有List,Set,Queue,和SortedSet四个。List可以存放重复的内容,Set不能存放重复的内容,所有重复的内容靠hashCode()和equals()两个方法区别。

二、List接口

List是Collection的子接口,其中可以保存各个重复的内容。接口的定义:

public interface List<E> extends Collection<E>

List接口扩充了Collection接口,拥有比其更为广泛的方法,List接口的所有扩展方法如下:

1、ArrayList子类

ArrayList子类可以为List接口进行实例化。ArrayList继承了AbstractList类,

public class ArratList<E> extends AbstractList<E> implements List<E> ,RandomAccess,Cloneable,Serializable

而AbstractList类实现了List接口。

public abstract class AbstractList<E> extends AbstractCollection <E> implements List<E>

因此可以直接使用ArrayList为List接口进行实例化。

public class ArrayListAdd {

	public static void main(String []args){
		List<String> allList=new ArrayList<String>();
		Collection<String> allCollection=new ArrayList<String>();
		allList.add("hello");
		allList.add(0,"world");//在0位置添加元素
		System.out.println(allList);//[world, hello]
		allCollection.add("hi");
		allCollection.add("MLDN");
		allList.addAll(allCollection);//在最后添加元素
		allList.addAll(0, allCollection);//在0位置添加元素
		System.out.println(allList);//[hi, MLDN, world, hello, hi, MLDN]
	}
}

每一个list都会被赋一个初始的容量,初始容量为10 

/**
     * Constructs an empty list with an initial capacity of ten.
     */

从上面的结果可以看出来,使用List中的add(int index,E)方法可以在集合中的指定位置增加元素,而add(E)只是在最后面添加。

remove()方法可以去除指定位置的元素,或者去除指定内容的元素。

allList.remove(0);//移除
System.out.println(allList);//[MLDN, world, hello, hi, MLDN]
allList.remove("MLDN");
System.out.println(allList);//[world, hello, hi, MLDN]
allList.remove("MLDN");
System.out.println(allList);//[world, hello, hi]

每次可以去除一个对象remove(Object o),每次去除一组对象removeAll(Collection<?> c),如果有多个相同类型的元素则需要多次去除;

通过取得长度的方法size(),然后使用get()方法可以将集合的指定位置的内容输出。

System.out.println(allList.size());//3
System.out.println(allList.get(1));//hello

通过头Array()方法可以将集合变为数组。以及截取集合subList(int,int)方法,是否为空isEmpty()方法,查找字符串位置indexOf(String)方法等。

2、Vector子类

Vector子类是比较老的一个类了,同样是继承于AbstractList<E>接口,

public class Vector<E>
    extends AbstractList<E>
    implements List<E>, RandomAccess, Cloneable, java.io.Serializable
{

因为和arraylist的区别不大,测试代码就不写了,arraylist是异步处理,是非线程安全的,只能使用Iterable和foreach输出。而Vector是同步出来,是线程安全的,可以使用Iterable,Enumeration和foreach输出

3、Linkedlist

LinkedList是一个链表的操作类,定义如下

public class LinkedList<E>
    extends AbstractSequentialList<E>
    implements List<E>, Deque<E>, Cloneable, java.io.Serializable

这个类不仅实现了list接口还实现了Duque接口,双向队列(Deque),是Queue的一个子接口,双向队列是指该队列两端的元素既能入队(offer)也能出队(poll),如果将Deque限制为只能从一端入队和出队,则可实现栈的数据结构。对于栈而言,有入栈(push)和出栈(pop),遵循先进后出原则,Queue接口是队列接口,是先进先出的方式。也就是说LinkedList类是双向列表,列表中的每个节点都包含了对前一个和后一个元素的引用.

public interface Deque<E> extends Queue<E> {
/**A linear collection that supports element insertion and removal at
 * both ends.  The name <i>deque</i> is short for "double ended queue"

最后Queue接口是实现了Collection接口

public interface Queue<E> extends Collection<E> {

通过上面可以看到LinkedList类是双向列表,列表中的每个节点都包含了对前一个和后一个元素的引用.这个类的两个构造方法

public LinkedList() {
    }//生成空的链表
public LinkedList(Collection<? extends E> c) {
        this();
        addAll(c);
    }// 复制构造函数

其实现的方法也比较多,这里就不一一介绍了,需要用的时候查一下就行了。

三 set接口

set接口也是collection接口的子接口,但是和他们不一样的地方就是它不能包含不一样的重复的对象元素。

1、HashSet子类

hashset是set接口的子类,存放的元素是无序但不可重复。

public static void main(String[] args) {
		// TODO 自动生成的方法存根
		Set<String> allSet=new HashSet<String>();
		allSet.add("a");
		allSet.add("a");		
		allSet.add("b");
		allSet.add("b");		
		allSet.add("b");
		allSet.add("c");
		allSet.add("f");
		allSet.add("s");
		allSet.add("d");		
		System.out.println(allSet);//调用tostring()方法
		
	}
输出[a, b, c, s, d, f]

2、TreeSet子类

TreeSet子类是set接口的子类,存放的元素是有序而且也不可以重复。这里的有序是指在输入数据以后他会进行一个自动的排序。

public class TreeSet<E> extends AbstractSet<E>
    implements NavigableSet<E>, Cloneable, java.io.Serializable
{

 他是继承了AbstractSet类,AbstractSet类又实现了Set接口

public abstract class AbstractSet<E> extends AbstractCollection<E> implements Set<E> {

下面是最简单的一个TreeSet的测试

Set<String> allset=new TreeSet<String>();
		allset.add("s");
		allset.add("a");
		allset.add("a");		
		allset.add("b");
		allset.add("b");		
		allset.add("b");
		allset.add("c");
		allset.add("f");
		allset.add("s");
		allset.add("d");
		System.out.println(allset);
输出结果
[a, b, c, d, f, s]

TreeSet的排序看起来就是这样,它会将所有非重复的元素就行排序,然后存储起来。我们看它的源码,在调用add方法以后,首先通过判断已经存储了这个值,然后他会返回一个boolean值。

public boolean add(E e) {
        return m.put(e, PRESENT)==null;
    }

未完待续。。。。

转载于:https://my.oschina.net/u/3471785/blog/1518649

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值