您现在的位置是:首页 > 文章详情

Java之集合(一)

日期:2019-07-17点击:414

Java最初版本只为最常用的数据结构提供了很少的一组类Vector、Stack、HashTable、BitSet和Enumeration接口,其中Enumeration接口提供了一种用于访问任意容器中各个元素的抽象机制.

集合框架的基本设计:将接口(interfaces)与实现(implementations)分离.
数据结构一队列
队列是指可以在队列的尾部添加元素,在队列的头部删除元素,并且可以 查找队列中元素的个数,按照先进先出的规则检索对象.
队列有两种实现方式,一种是循环组数,一种是链表.循环组数比链表更高效,但循环组数是一个有界集合,即容量有限,如果程序中要收集的对象数量没有上限,最好用链表来实现.

Collection接口:

集合类的基本接口是Collection接口,是集合层次中的根接口.下面先看下Collection接口中的方法:

  • int size(); 返回当前集合的元素个数
  • boolean isEmpty(); 判断集合是否为空,为空返回true
  • boolean contains(Object o); 如果此集合包含指定的元素,则返回true
  • Iterator iterator(); 返回此集合中元素的迭代器,用于访问集合中的每一个元素
  • Object[] toArray(); 返回包含此集合中所有元素的数组。
  • T[] toArray(T[] a); 返回包含此集合中所有元素的数组;如果T足够大,就将集合中的元素添加到此数组,剩余空间填补null,否则分配一个新数组,类型与T一直,数组长度等于集合大小,填充集合元素
  • boolean add(E e); 将元素添加到集合中,成功返回true
  • boolean remove(Object o); 从集合中删除匹配到对象o的元素,删除成功返回true
  • boolean containsAll(Collection<?> c); 如果集合包含指定集合的所有元素,返回true
  • boolean addAll(Collection<? extends E> c); 将指定集合中的所有元素添加到此集合
  • boolean removeAll(Collection<?> c); 移除方法中还包含此集合的所有元素
  • default boolean removeIf(Predicate<? super E> filter) 移除此集合中满足给定条件的所有元素
  • boolean retainAll(Collection<?> c); 仅保留此集合中包含的元素
  • void clear(); 从该集合中删除所有元素
  • boolean equals(Object o); 将指定的对象与此集合进行相等性比较
  • int hashCode(); 返回此集合的哈希码
    1.8
  • default Spliterator spliterator() 在此集合上创建一个spliterator迭代器
    1.8
  • default Stream stream() 返回该集合的流
    1.8
  • default Stream parallelStream() 返回一个可能与此集合并行的流,该方法允许返回顺序流
    add()方法用于添加元素,添加成功集合元素改变返回true,若是添加的元素在集合中已经存在,集合元素没有发生改变,则返回false,因为集合中不允许重复.iterator()方法用于返回一个实现了Iterator接口的对象.可以使用这个迭代去对象一次访问集合中的元素.

迭代器:

Iterator接口中包含四个方法,如下:

  • boolean hasNext(); 如果存在可访问元素返回true
  • E next(); 返回将要访问的下一个对象.如果到达集合尾部,会抛出NoSuchElementException
  • default void remove()删除上次访问对象.正则方法必须跟在访问一个元素之后执行,否则将抛出IllegelStateException
  • default void forEachRemaining(Consumer<? super E> action) 为每个剩余元素执行给定的操作,直到所有元素已处理或操作引发异常
    通过反复调用next()方法,可以依次访问集合中的每个元素,但是如果到达集合的末尾.next()将抛出一个NoSuchElementException异常,因此,需要在调用next()方法之前调用hasNext()方法,如果还有课供访问的元素,就返回true,若要查看一个集合的所有元素,就请求一个迭代器,在hashNext()方法饭后true时反复调用next()方法.

示例一:
不调用hasNext()方法

class Test{ public static void main(String[] args) { Collection<String> stringCollection = new ArrayList<>(); Collection<String> collection = new ArrayList<>(); collection.add("aaa"); collection.add("bbb"); collection.add("ccc"); stringCollection.add("ddd"); stringCollection.add("eee"); stringCollection.add("fff"); collection.addAll(stringCollection); Iterator iterator = collection.iterator(); while (collection.size()>0){ Object o = iterator.next(); System.out.println(o); } } }

运行结果

image

示例二:
调用hasNext()方法

class Test{ public static void main(String[] args) { Collection<String> stringCollection = new ArrayList<>(); Collection<String> collection = new ArrayList<>(); collection.add("aaa"); collection.add("bbb"); collection.add("ccc"); stringCollection.add("ddd"); stringCollection.add("eee"); stringCollection.add("fff"); collection.addAll(stringCollection); Iterator iterator = collection.iterator(); while (iterator.hasNext()){ Object o = iterator.next(); System.out.println(o); } } }

运行结果
image
也可以用for each循环进行更加简便的操作,Collection接口实现了Iterable接口,for each循环可以同任何实现了Iterable接口的对象一起工作,在1.8之前1.5之后Iterable接口只包含了一个方法.在1.8新增了两个方法

  • Iterator iterator(); 此接口允许对象成为for each循环的目标
    1.8
  • default void forEach(Consumer<? super T> action) 遍历所有元素,直到查出所有元素或抛出异常
    1.8
  • default Spliterator spliterator() 创建一个spliterator迭代器
    在Java1.8中,可以不写循环,直接调用forEachRemaining()方法,并提供一个lambda表达式(处理一个元素),迭代器的每一个元素都调用这个lambda表达式,直到没有元素为止.用上面的for each的例子稍微修改如下:
class Test{ public static void main(String[] args) { Collection<String> stringCollection = new ArrayList<>(); Collection<String> collection = new ArrayList<>(); collection.add("aaa"); collection.add("bbb"); collection.add("ccc"); stringCollection.add("ddd"); stringCollection.add("eee"); stringCollection.add("fff"); collection.addAll(stringCollection); Iterator iterator = collection.iterator(); iterator.forEachRemaining(String -> System.out.println(String)); } }

运行结果
image

元素被访问的顺序取决于集合类型,如果对ArrayList进行迭代,迭代器将从索引0开始,没迭代一次,索引值加1,如果是访问HashSet中的元素,每个元素会按照某种随机的次序出现,可以遍历所有元素,但无法预知元素被访问的顺序.
Iterator接口的remove()方法会删除上次调用next()方法是返回的元素,在调用remove()方法之前必须先调用next()方法,如果不调用next()方法直接调用remove方法,会抛出IllegalStateException异常.next()方法与remove()方法具有相互依赖性.
示例一:
直接调用remove()方法

class Test{ public static void main(String[] args) { Collection<String> stringCollection = new ArrayList<>(); Collection<String> collection = new ArrayList<>(); collection.add("aaa"); collection.add("bbb"); collection.add("ccc"); stringCollection.add("ddd"); stringCollection.add("eee"); stringCollection.add("fff"); collection.addAll(stringCollection); Iterator iterator = collection.iterator(); iterator.remove(); } }

运行结果

image

示例二:
先调用next()方法后调用remove()方法

 public static void main(String[] args) { Collection<String> stringCollection = new ArrayList<>(); Collection<String> collection = new ArrayList<>(); collection.add("aaa"); collection.add("bbb"); collection.add("ccc"); stringCollection.add("ddd"); stringCollection.add("eee"); stringCollection.add("fff"); collection.addAll(stringCollection); Iterator iterator = collection.iterator(); iterator.next(); iterator.remove(); iterator.forEachRemaining(String -> System.out.println(String)); } }

运行结果
image
删除下标为0的
Collection接口和Iterator接口都是泛型接口,可以编写操作任意类型的方法.
Java集合框架为不同类型的集合定义大量的接口,集合有两个基本接口:Collection和Map.
List是一个有序集合,元素会增加到容器的特定位置,可以采用laingzh两种方式访问元素,使用迭代器或者使用证书索引来访问,使用迭代器访问,必须是有序的访问,整数索引访问则可以随机任意顺序访问元素.
Set接口类似Collection接口,不过方法更加严谨,Set的add()方法不允许添加重复元素.
在这里可以引出一个经典的面试题
List和Set的区别:
List(列表):

  • 有序
  • 可重复
  • 元素都有索引,可通过索引访问元素
    Set(集):
  • 无序
  • 不可重复

上面对集合的做了简单的介绍,其他的内容会在后面的博客再做介绍,若发现错误和不足之处,欢迎指正.

原文链接:https://yq.aliyun.com/articles/709877
关注公众号

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。

持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。

转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。

文章评论

共有0条评论来说两句吧...

文章二维码

扫描即可查看该文章

点击排行

推荐阅读

最新文章