集合


集合框架位于java.util.*

 

接口Collection<E>------子接口List<E>,Set<E>

 

数组和集合类同是容器,区别:

1.数组长度固定,集合长度可变

2.数组可以存储对象和基本数据类型,集合只能存储对象

 

List与Set的区别:

List是可重复的,可随机访问,不可排序,唯一性:equals;

Set是不重复的,不可随机访问,可排序,唯一性:ListSet - hashCode+equals/TreeSet - compareTo;

 

一、Collection<E>

根跟接口Collection定义了许多集合通用的方法:

1.添加

boolean add(E e)

boolean addAll(Collection<? extends E> c)//可以添加一个E的子系类的集合

2.删除

void clear()//清空集合

boolean remove(Objecto)//移除o

boolean removeAll(Collection<?>c)//移除集合对象中同时包含在c集合中的元素

boolean retainAll(Collection<?>c) //保留集合对象中同时包含在c集合中的元素

3.判断

boolean contains(Object o)//集合含有对象o则返回true

boolean containsAll(Collection<?> c)//若此集合对象含有集合c中所有元素则返回true

boolean isEmpty() //空集合则返回true

4.获取

int size()//返回集合中元素个数

Iterator<E> iterator()//返回在此 collection 的元素上进行迭代的迭代器。

Object[] toArray()//返回包含此集合中所有元素的数组。

<T> T[] toArray(T[] a)//前者的增强版

a返回的数组<T> T[]的运行时类型<T>是指定的数组a的运行时类型<T>

b若指定数组a可以容纳集合中的元素则返回此数组a,若a有剩余空间则用null填充

c如果a无法容纳则将分配一个具有指定数组a的运行时类型<T>的且其大小与数组元素数量相同的新数组。

//Collection<String> c

String[] newStringArray = c.toArray(new String[0]);//长度为0的String数组必定不能容纳c的元素,则分配一个与String数组同类型的String[]存放集合的元素,而这个新的String[]的长度与集合元素数量相同。

 

boolean    equals(Objecto) //比较此 collection 与指定对象是否相等。

int    hashCode()//返回此 collection 的哈希码值。

 

二、Iterator<E>

迭代器Iterator<E> 集合取出元素的方式,定义在集合内部。

共性:判断和取出,会自动消亡

可以通过集合的iterator()获取对应的对象的迭代器

Iterator itor=al.iterator();

方法:

boolean hasNext()//迭代器下一个指向元素是否存在

E next()//返回迭代器所指向的元素的索引,并将迭代器向后移动一个位置

void remove()//删除迭代器当前所指向的元素。每次使用next最多只能使用一次remove

 

ArrayList a=newArrayList();

 

for(Iterator itor =a.iterator();iter.hasNext();){

System.out.println(iter.next());

}

Iterator itor2 = a.iterator();

while(itor2.hasNext()){

System.out.println(iter.next());

}

 

三、List<E>

判断元素是否相同,依据的是元素的equals方法(remove,contains底层使用的也是equals)

凡是可以直接处理下标的方法都是List所特有的

 

1.添加

void  add(int index, E element)//在列表的指定位置插入指定元素

boolean    addAll(int index, Collection<? extendsE> c) 将集合c中的元素从指定位置开始插入

2.删除

Eremove(int index)//移除列表中指定位置的元素并将之返回

3.修改

Eset(int index, E element)//用指定元素替换列表中指定位置的元素,返回原值

4.获取

E get(int index) //返回列表中指定位置的元素。

int indexOf(Object o)//返回o在集合中第一次出现的位置,若无则返回-1

int lastIndexOf(Object o) //返回o在集合中最后一次出现的位置,若无则返回-1

 

List<E> subList(int fromIndex, inttoIndex)//返回从fromIndex到toIndex(不含)的子列表

 

ListIterator<E> listIterator()//返回此列表元素的列表迭代器

ListIterator<E>         listIterator(int index) //返回此列表元素从index开始的列表迭代器

 

 

Iterator只能删除不能添加。使用Iterator时不能既使用集合的方法,又使用迭代器方法。会发生ConcurrentModificationException异常。

在迭代器时,只能用迭代器的方法操作元素,只能对元素进行判断,取出,删除的操作。

 

 

ListIterator

List特用的迭代器,因为List是有序的,所以可以在迭代时进行增删等操作

方法:

添加void add(E e) //将指定的元素插入列表

删除void remove() //从列表中移除由 next 或 previous 返回的最后一个元素

修改void set(E e)//用指定元素替换 next 或 previous 返回的最后一个元素

 

向后迭代:

boolean hasNext() //以正向遍历列表时,如果列表迭代器有多个元素,则返回 true(换句话说,如果 next 返回一个元素而不是抛出异常,则返回 true)。

E next() //返回列表中的下一个元素。

int nextIndex()//返回下一个元素的索引,尾部为列表的大小

向前迭代:

boolean hasPrevious() //如果以逆向遍历列表,列表迭代器有多个元素,则返回 true。

E previous()//返回列表中的前一个元素。

int previousIndex()//前一个元素的索引,首部为-1

四、Vector

LinkedList 底层是链表,增删快,查询速度慢,线程不同步

ArrayList 底层是数组,增删慢,查询速度快,线程不同步

Vector      底层是数组,速度慢,但是线程安全

 

Vector

方法:(XxxElement是Vector特有方法)

void addElement(obj);//添加元素到末尾

E elementAt(int index)//返回指定索引处的组件

void  insertElementAt(Eobj, int index)//将对象obj作为此向量中的组件插入index所指位置

Vector取出元素的方法

1.迭代listIterator()/iterator()

2.遍历中使用get(list的子类,可以使用for)

E get(int index)//返回向量中指定位置的元素。与E elementAt(int index)方法功能相同,但get是List接口的一部分,elementAt是特有方法

3.枚举:

Enumeration elements();//Vector特有取出方式(枚举)

Enumeration的两个方法:

boolean hasMoreElements();//相当于Iterator的hasNext()方法

nextElement();//相当于Iterator的next()方法


五、LinkedList

LinkedList:底层使用的是链表数据结构。特点:增删速度很快,查询稍慢。

特有方法:

1.添加

       addFirst();

       addLast();

2.获取

       //获取元素,但不删除元素。如果集合中没有元素,会出现NoSuchElementException

       getFirst();

       getLast();

3.删除

       //获取元素,并删除元素。如果集合中没有元素,会出现NoSuchElementException

       removeFirst();

       removeLast();

在JDK1.6以后,出现了替代方法。

1.添加

       offFirst();

       offLast();

2.获取

       //获取元素,但是不删除。如果集合中没有元素,会返回null。

       peekFirst();

       peekLast();

3.删除

       //获取元素,并删除元素。如果集合中没有元素,会返回null

       pollFirst();

       pollLast();

六、set

Set:元素是无序(存入和取出的顺序不一定一致),元素不可以重复。    

|--HashSet:底层数据结构是哈希表。线程不同步。保证元素唯一性的原理:判断元素的hashCode值是否相同。如果相同,还会继续判断元素的equals方法,是否为true

|--TreeSet:可以对Set集合中的元素进行排序。默认按照字母的自然排序。底层数据结构是二叉树。保证元素唯一性的依据:compareTo方法return  0则相同。

Set集合的功能和Collection是一致的。

(一)HashSet-Hash表

特点:

1.元素重复性:元素不可以重复

         判断重复的标准:

                   1.比较对象的hashcode

                   2.若hashcode相同则比较equals

contains()/remove()等操作底层依赖hasCode()以及equals()

2.存储顺序特性:无序存储。不是按添加顺序,而是按照hash值顺序存储,若hash值相同而equals为false则在前一个相同hashcode实例对象的后面存储新的对象。

         若hashCode结果相同而equals结果为true,则表示两个对象为同一对象,则不予添加,返回false。

         假设有类Testing,则HashSet<Testing>迭代后打印显示的是类似testing@c17164的结果。@前为类名,@后为实例对象的hash值

3.取出方法:只能通过迭代器取出添加进Set的实例对象。

4.线程安全性:线程不同步

5.存取速度:存取速度快

 

注意:当HashSet添加两个值相同的对象时,首先比较的是hash值,如果使用的是默认的hashCode,因存储位置不同,结果是不同的hash的话,是不会再调用equals进行下一步比较,直接当作两个不同对象。

(二)TreeSet-二叉树

特点:

1.元素重复性:元素不可以重复

         判断重复的标准:

                   1.TreeSet中的元素需要具有比较性,否则会产生ClassCastException

                   2.通过compareTo方法的返回值判断是否相同

                            String类的默认比较方法是Unicode编码顺序

2.存储特性:有序存储。但不能随机访问。按照所设定的排序方法进行排序。

3.取出方法只能通过迭代器取出添加进Set的实例对象。

4.线程安全性:线程不同步

5.访问特性中序遍历

 

实现排序的两种方法:(必须)

1.元素的类实现Comparable接口,覆盖int compareTo(T o)

2.如果元素不具备比较性(没有实现Comparable接口),或者默认的排序不是所需时,须要让集合自身具备比较性。

构造函数传入一个比较器参数

         TreeSet<E>(Comparator<?super E> comparator)

Comparator接口需要实现intcompare(T o1, T o2)方法

 

Comparator接口与Comparable接口的区别:

Comparator位于java.lang.util.*                               Comparable位于java.lang.*;

 需要实现int compare(T o1,T o2)                            需要实现intcompareTo(T o)

 

当Comparable与Comparator都存在,Comparator为主


七、Map

Map

|--Hashtable:底层是哈希表数据结构,不可以存入nullnull。该集合是线程同步的。JDK1.0,效率低。

|--HashMap:底层是哈希表数据结构。允许使用nullnull,该集合是不同步的。JDK1.2,效率高。

|--TreeMap:底层是二叉树数据结构。线程不同步。可以用于给Map集合中的键进行排序

Set底层就是使用了Map集合。

(一)特点

    1.双列集合,存储的是键(key)值(value)对。一对一对往里存

    2.要保证key的唯一性

(二)Map集合的常用方法

1.添加

V put(K key,Vvalue);//添加元素,如果出现添加时,相同的键,那么后添加的值会覆盖原有键对应值,并put方法会返回被覆盖的值。

void putAll(Map<? extends K,? extends V> m);//添加一个集合

2.删除

clear();//清空

V remove(Object key);//删除指定键值对,并返回被删除键值对的值

3.判断

containsKey(Objectkey);//判断键是否存在

containsValue(Objectvalue)//判断值是否存在

isEmpty();//判断是否为空

4.获取

       V get(Object key);//通过键获取对应的值

       size();//获取集合的长度

       Collection<V> value();//获取Map集合中所有所谓值,返回一个Collection集合

(三)Map集合的两个视图

Map集合的两个视图(实现了Collection接口/子接口对象的视图)

键集,键值对集,(还有一个视图是值集合)

KeySetEntrySet不是HashSet和TreeSet,而是实现了Set接口的某个其他类。而Set接口扩展了Collection接口,可以使用集合的所有方法

 

1. keySet

Set<K> keySet():将Map中所有的键存入到Set集合。因为Set具备迭代器。所以可以通过迭代方式取出所以键的值,再通过get方法。获取每一个键对应的值。

//Map<String,String> m=newHashMap<String,String>();

Set<String> keyS=m.keySet();

for(Iterator<String>itor=keyS.iterator();itor.hasNext();){

         Stringtmp=itor.next();

         System.out.println(m.get(tmp))

}

 

2. entrySet

Set<Map.Entry<K,V>> entrySet():将Map集合中的映射关系存入到Set集合中,而这个关系的数据类型就是:Map.Entry

      其实,Entry也是一个接口,它是Map接口中的一个内部接口(内部接口默认是publicstatic)。 

interface Map{ 

public staticinterface Entry{ 

public abstract Object getKey(); 

public abstract Object getValue(); 

         }

 }

定义在Map内部的原因:

1. Map中存储的是键值对,先有Map才会有键值对,是Map的内部事务。

2.是Map映射表中的元素使用Entry,应当可以直接访问Map中的内部成员。(内部类,为了使用外部类的成员

 

//Map<String,String> m=newHashMap<String,String>();

Set<Map.Entry<String,String>>entryS=m.entrySet();

for(Iterator<Map.Entry<String,String>>itor=entryS.iterator();itor.hasNext();){

         Map.Entry<String,String>tmp=itor.next();

         Stringkey=tmp.getKey();

         Stringvalue=tmp.getValue();

}



集合框架中的两个工具类Collections和Arrays

八、Collections

(一)特点

1.包装类,完全由 在 collection 上进行操作 或 返回 collection 的静态方法组成。它包含在 collection 上操作的多态算法,即“包装器”,包装器返回由指定 collection 支持的新 collection,以及少数其他内容。

2.如果为此类的方法所提供的collection或类对象为null(提供的参数为null),则这些方法都将抛出 NullPointerException

3.在Collections工具类中大部分方法是用于对List集合进行操作的,如比较,二分查找,随机排序等。

4.没有对外提供构造函数 

(二)常见操作方法

1.反转

       reverse(List<?>list);// [List]反转list集合中元素的顺序

       Comparator reverseOrder();//返回一个比较器,强行逆转了实现Comparable接口的对象的自然顺序

       Comparator reverseOrder(Comparator<T>cmp);//返回一个比较器,强行逆转了指定比较器的顺序

2.排序[List]

       void shuffle(List<?> list);//使用默认随机源对list集合中的元素进行随机排序

       void sort(List<T> list);//根据自然顺序对list集合中的元素进行排序

       void sort(List<T> list,Comparator<? super T> c);//根据指定比较器c的排序方式对list集合进行排序

3.查找

       T max/min(Collection<? extends T> coll);//根据集合的自然顺序,获取coll集合中的最大(小)元素

       T max/min(Collection<? extends T> coll,Comparator<? super T>comp);//根据指定比较器comp的顺序,获取coll集合中的最大(小)元素

使用二分法查找前应当先用sort排序否则结果将不确定

       int binarySearch(List<? extends Comparable<? super T>> list,T key);//[List]二分法搜索list集合中的指定对象

int binarySearch(List<? extendsComparable<? super T>> list,T key,Comparator<? super T> comp);//[List]根据指定比较器comp的顺序,二分法搜索list集合中的指定对象

4.替换[List]

       void fill(List<? super T> list, T obj);//全部替换一个元素。将list集合中的全部元素替换成指定对象obj

       boolean replaceAll(List<T> list,T oldVal,T newVal);//指定内容的元素的替换。用newVal替换集合中的oldVal值

       void swap(List list,int i,int j);/在指定列表的指定位置处交换元素

5.同步的集合

       List<T> synchronizedList(List<T> list);// [List]返回支持的同步(线程安全的)List集合

       Map<K,V> synchronizedMap(Map<K,V> m);// [Map]返回支持的同步(线程安全的)Map集合

(三)Collections和Collection的区别

Collection是集合框架中的一个顶层接口,它里面定义了单列集合的共性方法

它有两个常用的子接口:

List:对元素都有定义索引。有序的。可以重复元素。       

Set:不可以重复元素。无序

Collections是集合框架中的一个工具类。该类中的方法都是静态的。提供的方法中有可以对list集合进行排序,二分查找等方法

通常常用的集合都是线程不安全的。因为要提高效率。如果多线程操作这些集合时,可以通过该工具类中的同步方法,将线程不安全的集合,转换成安全的。


九、Arrays

Arrays - 用于操作数组的工具类,全部是静态方法

1.获取

复制copyOf():复制指定的数组,截取或用 0/null填充(如有必要),以使副本具有指定的长度。

         statictypename [] copyOf(typename[]original,int newLength)

比如:static int[]copyOf(int[] original, int newLength)

         static int[] copyOfRange(int[]original,intfrom,int to)

二分法搜索binarySearch(),

         staticint binarySearch(typename[]a,intfromIndex,int toIndex,typename key)

比如:static intbinarySearch(double[] a, int fromIndex, int toIndex, double key)

返回的是key在数组中的位置。如果没找到则返回(-(插入点) - 1)

2.修改

替换fill(typename[] a,typename key )

         fill(typename[]a,int fromIndex,int toIndex,typename key )

排序sort(typename[] a)

         sort(typename[]a,int fromIndex,int toIndex)

         sort(T[]a,intfronIndexmint toIndex,Comparator<? super T>comp)

3.三个常用的方法

equals:Object的只能比较单个对象,Arrays中的静态equals可以比较2个数组

hashCode: Object的返回的是单个对象的哈希值,Arrays中静态的hashCode可以返回一个代表整个数组的元素的hash值,方便整个类对象计算hash值

toString:对于数组来说,默认的toString 返回的是地址,而不是内容,而Arrays中的静态toString则可以返回整个数组的内容。 

import java.util.Arrays;
public classtest2 {
    public static void main(String[] args) {
       //equals
       //static boolean equals(T[] a1, T[] a2)
           System.out.println(Arrays.equals(new int[]{1,2,3},new int[]{1,2,3}));//true
       //hashCode
       //static int hashCode(T[] a)
           System.out.println(Arrays.hashCode(new String[]{"hello","bye"}));//-1220836323
       //toString
       //static String toString(T[] a)
           System.out.println(Arrays.toString(new double[]{3.14,1.23}));//[3.14, 1.23]
    }
}

4.数组变为集合

List<T> asList(T... a);//将数组转换为集合

1将数组转换成集合,不可使用集合的增删方法,因为数组的长度是固定的。如果进行增删操作,则会产生UnsupportedOperationException的编译异常。

2如果数组中的元素都是对象,则变成集合时,数组中的元素就直接转为集合中的元素。

3如果数组中的元素都是基本数据类型,那么会将该数组作为集合中的元素存在。

 

集合变数组限制对元素的操作,让其他的对数组的调用不可以增加或者删除元素:

每个集合类都有toArray()方法

<T> T[] toArray(t[] a)

集合元素数目大于数组长度,重新建立一个新数组存放集合的元素。

集合元素数目小于数组长度,用null填充

创建一个等大数组

String[] arr=al.toArray(newString[al.size()]);

String[] arr2=al.toArray(new String[0]);



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值