Java中容器总结

集合的由来

对象用于封装特有数据,对象多了需要存储,如果对象的个数不确定,就使用集合进行存储。

集合特点

  • 用于存储对象的容器。
  • 集合的长度是可变的。
  • 集合中不可以存储基本数据类型的值。

集合容器因为内部的数据结构不同,有多种具体容器,不断向上抽取形成了集合框架,框架顶层Collection接口。

Collection的常见方法:

  • 添加
    • boolean add(Object obj);
    • boolean addAll(Collection coll);
  • 删除
    • boolean remove(Object obj);
    • boolean removeAll(Collection coll);
    • void clean();
  • 判断
    • boolean contains(Object obj);
    • boolean containsAll(Collection coll);
    • boolean ifEmpty();  判断集合中是否有元素  
  • 获取
    • int size();  获取集合长度
    • iterator();  通过迭代器取出元素,该对象必须依赖具体容器,因为每一个容器的数据结构都不同。所以该迭代器对象是在容器中进行内部实现的 。对于使用容器者而言,具体的实现不重要,只要通过容器获取到该实现的迭代器对象即可,也就是iteration方法。Iterator接口就是对所有的Collection容器进行元素取出的公共接口。
  • 其他
    • boolean retainAll(Collection coll);  取两个集合的交集元素。
    • Object[ ] toArray();  将集合转换成数组。

Collection接口:Collection接口下又分为List接口和Set接口

|--List接口:  有序(存入和取出的顺序一致),元素都有索引(角标),元素可以重复。

|--Set接口:  元素不能重复,无序。

List接口:特有的常见方法,有一个共性特点就是都可以操作角标。

List接口的方法:

  • 添加
    • void add(index,element);
    • void add(index,Collection);
  • 删除 
    • Object remove(index);
  • 修改
    • Object set(index,element);
  • 获取
    • Object get(index);
    • int indexOf(object);
    • int lastInedxOf(object);
    • List subList(from,to);  获取子列表含头不含尾  

List集合是可以完成对元素增删改查操作的。

在List接口下又实现了以下三给类:Vector、ArrayList、LinkedList。

List接口:

|--Vector:内部是数组数据结构,是线程同步的,是线程安全的,增删查询都很慢!

|--ArrayList:内部是数组数据结构,是线程不同步的,替代Vector,查询速度快,因为数组内存空间是连续的所以查找起来就很快。

|--LinkedList:内部是链表数据结构,是线程不同步的,增删元素的速度很快。

接下来分别来介绍实现List接口的Vector,ArrayList,LinkedList三个类。

Vector

  • void addElement();
  • 由于Vector是线程同步的,增删插叙速度都很慢,所以我就不做过多的介绍,就针对Vector的Enumeration接口进行介绍。在Vector中我们可以使用  Enumeration enumeration=vector.elements();来遍历Vector中的元素。Enumeration接口类似于Iterator接口,但是由于名字过长直接淘汰了。

LinkedList

  • addFirst();
  • addLast();
  • getFirst();  获取元素但是不移除,如果链表为空,抛出NoSuchElementException
  • getLast();
  • peekFirst();  获取元素但是不移除,如果链表为空,返回null
  • peekLast();
  • removeFirst();  获取元素并移除元素,如果链表为空,抛出NoSuchElementException
  • removeLast();
  • pollFirst();  获取元素并移除元素,如果链表为空,返回null

ArrayList:

ArrayList实现了List接口,其ArrayList方法跟List中方法是一致的,替代了Vector在此就不在做介绍了。

Set接口:Set元素是不可以重复的,是无序的,Set接口中的方法和Collection中的方法是一致的。在Set接口下我们通常使用实现Set接口的子类,HashSet和TreeSet。

Set接口:

|--HashSet:内部数据结构是哈希表,是不同步的。

|--TreeSet:内部数据结构是二叉树或者说是红黑树,可以对Set集合中的元素进行排序,是不同步的。

接下来分别介绍实现了Set接口的HashSet和TreeSet类。

HashSet

针对于HashSet类我们首先讲一下哈希表如何确定元素是否相同:

  • 判断两个元素的哈希值是否相同,如果相同,在判断两个对象的内容是否相同。
  • 判断哈希值相同,其实就是判断对象的hashCode方法,判断内容相同,用的是equals的方法。
  • 如果哈希值不同是不用判断equlas的。
  • 推论:如果两个元素的equals相同,哈希值一定相同,如果哈希值相同,两个元素的内容不一定相同。

在HashSet中如何保证该集合元素的唯一性呢?

是通过对象的hashCode和equals方法来完成对象唯一性的。

如果对象的hashCdoe值不同,那么不用判断equals方法,就直接存储到哈希表当中。

如果对象的hashCode值相同,那么再次判断对象的equals方法是否为true,如果为true则视为相同元素,不存。如果为false则视为不同元素,就进行存储。

记住:如果元素要存储到HashSet集合中,必须覆盖hashCode方法和equals方法,一般情况下,如果定义的类会产生很多对象,比如说人,学生,书,通常都需要覆盖equals,hashCode方法,建立判断对象是否相同的依据。相比于ArrayList来讲,HashSet是通过hashCode和equals来判断是否相同,而ArrayList是仅仅通过equals来判断对象是否相同。

LinkedHashSet

LinkedHashSet继承了HashSet,LinkedHashSet中维护了一个双向链表从而使得HashSet中的内容唯一且有序。

TreeSet

在TreeSet类中判断元素唯一性的方法就是根据比较方法返回的结果是否是0,如果是0,就是相同元素,不存。所以如果要改变TreeSet中元素的排序顺序,我们可以覆写比较方法。

TreeSet对元素进行的排序方式一:

让元素自身具备比较功能,元素类就需要实现Comparable接口,覆盖compareTo方法。

但是我们在实际开发中一般是不会修改一个类内部的函数或者成员变量的,所以我们需要让集合自身具备比较功能。

TreeSet对元素进行的排序方式二:

定义一个类实现Comparator接口,覆盖compare方法,将该类对象作为参数传递给TreeSet集合的构造函数。

小结:

List

|-----------------ArrayList

|-----------------LinkedList

Set

|-----------------HashSet

|-----------------TreeSet

集合的一些技巧:

需要唯一?

需要:Set

  • 需要制定顺序:
    • 需要:TreeSet
    • 不需要:HashSet
    • 但是想要一个和存储一致的顺序(有序):LinkedHashSet

不需要:List

  • 需要频繁增删吗?
    • 需要:LinkedList
    • 不需要:ArrayList

如何记录每一个容器的结构和所属体系呢?

看名字!

后缀名就是该集合所属的体系。前缀名就是该集合的数据结构。

看到array:就要想到数组,就要想到查询块,有角标。

看到link:就要想到链表,就要想到增删快,就要想到add,get,remove+first  last的方法。

看到hash:就要想到哈希表,就要想到唯一性,就要想到元素需要覆盖hashCode方法和equals方法。

看到tree:就要想到二叉树,就要想到排序,就要想到两个接口Comparator,Comparable。

而且通常这些常用的集合容器都是不同步的。

Map接口的常见方法:

Map:一次添加一对元素,Collection一次添加一个元素,Map为双列集合,Collection为单列集合。其实Map集合中存储的就是键值对。Map集合中必须保证键的唯一性。

常用方法:

  • 添加:
    • value put(key,value):返回前一个和key关联的值,如果没有与key关联的值,返回null。
  • 删除
    • void clear():清空map集合。
    • value remove(key):根据指定的key删除这个键值对。
  • 判断
    • boolean containsKey(key)
    • boolean containsValue(value)
    • boolean isEmpty()
  • 获取
    • value get(key):通过键获取值,如果没有该键返回null。当然可以通过返回null,来判断是否包含指定键。
    • int size():获取键值对的个数。

Map常用的子类:

|--Hashtable:内部数据结构是哈希表,是同步的。不允许null作为键,null作为值。

|--HashMap:内部数据结构是哈希表,是不同步的。允许null作为键,null作为值。

|--TreeMap:内部数据结构是二叉树,不是同步的。可以对Map集合中的键进行排序。

HashMap:

HashMap中存储的元素是无序的。如果我们想要将数据变成和存储数据一致的顺序,我们可以使用LinkedHashMap。

TreeMap:

TreeMap中存储的数据元素是有序的。如果我们想要改变TreeMap中的排列顺序我们可以覆写其中的比较方法。

TreeMap对元素进行的排序方式一:

让元素自身具备比较功能,元素类就需要实现Comparable接口,覆盖compareTo方法。

但是我们在实际开发中一般是不会修改一个类内部的函数或者成员变量的,所以我们需要让集合自身具备比较功能。

TreeMap对元素进行的排序方式二:

定义一个类实现Comparator接口,覆盖compare方法,将该类对象作为参数传递给TreeSet集合的构造函数。

Collections工具类的介绍:

Collections是集合方法的工具类,里面的方法都是静态的。

  • Collections方法:
  • shuffle();随机把元素安放在集合中的任意位置上。
  • replaceAll();j将集合中的某个元素替换掉。实现方法为:ste(indexOf("元素1"),"元素2");
  • fill();将集合中的所有元素都替换掉。
  • reverseOrder(new comparator());可以将集合中的元素进行反转,也可以将比较方法反转。
  • binarySearch();二分查找,前提是集合一定是有序的。如果返回为负值表示没找到,负的数值表示插入点加一。返回整数就代表找到了。
  • max(集合,比较器);可以添加比较器,可以按照比较器的规则寻找最大值。
  • sort(集合,比较器);可以添加比较器,可以对集合进行排序。

Arrays集合的方法介绍:

Arrays集合里面的方法都是静态的。

将数组转换成集合:Arrays.toString(arr)

List asList(数组)将数组转换成集合。好处:其实可以使用集合的方法操作数组中的元素,注意就是数组长度是固定的,所以对于集合的增删方法是不可以使用的否则会发生UnsupportedOperationException。如果数组中的元素是对象,那么转换成集合时,直接将数组中的元素作为集合中的元素进行集合存储。如果数组中的元素是基本类型数据,那么会将该数组作为集合中的元素进行存储。

将集合转换成数组:集合.toArray(new 类型[数组长度])

使用Collection接口中的toArray方法将集合转换成数组。将集合转换成数组可以对集合中的元素操作的方法进行限定。不允许对其增删。在toArray方法中,如果传入的数组的长度小于集合的size,那么该方法会创建一个同类型并和集合相同的size的数组。如果长度大于集合size那么该方法就会使用指定的数组,存储集合中的元素,其他位置默认为null。所以建议,最后长度就指定为集合的size。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值