Loading

Java集合02

1. Set集合

(1) Set集合的特点
  无序,唯一
(2) HashSet集合
  A:底层数据结构是哈希表(是一个元素为链表的数组)
  B:哈希表底层依赖两个方法:hashCode()和equals()
    执行顺序:
      首先比较哈希值是否相同
      相同:继续执行equals()方法
        返回true:元素重复了,不添加
        返回false:直接把元素添加到集合
      不同:就直接把元素添加到集合
  C:如何保证元素唯一性的呢?
    由hashCode()和equals()保证的
  D:开发的时候,代码非常的简单,自动生成即可
  E:HashSet存储字符串并遍历
  F:HashSet存储自定义对象并遍历(对象的成员变量值相同即为同一个元素)
  G:不保证set的迭代顺序,特别是它不保证该顺序恒久不变
(3) LinkedHashSet集合
  A:元素有序唯一。由链表保证元素有序,由哈希表保证元素唯一
(4) TreeSet集合
  A:底层数据结构是红黑树(是一个自平衡的二叉树) -> 保证元素的排序和唯一性
  B:保证元素的排序方式
    a:自然排序(元素具备比较性)
      让元素所属的类实现Comparable接口
    b:比较器排序(集合具备比较性)
      让集合构造方法接收Comparator的实现类对象
(5) 遍历
  A:HashSet集合
    a:用Iterator来遍历
    b:用增强for来遍历
  B:TreeSet集合

2. Collection集合总结
Collection
  |--List 有序,可重复
    |--ArrayList
      底层数据结构是数组,查询快,增删慢。
      线程不安全,效率高
    |--Vector
      底层数据结构是数组,查询快,增删慢。
      线程安全,效率低
    |--LinkedList
      底层数据结构是链表,查询慢,增删快。
      线程不安全,效率高
  |--Set 无序,唯一
    |--HashSet
      底层数据结构是哈希表。
      如何保证元素唯一性的呢?
        依赖两个方法:hashCode()和equals(),开发中自动生成这两个方法即可
      执行顺序:
        首先判断hashCode()值是否相同
          是:继续执行equals(),然后看其返回值,是true:说明元素重复,不添加,是false:就直接添加到集合
          否:就直接添加到集合
        最终:自动生成hashCode()和equals()即可
    |--LinkedHashSet
      底层数据结构是链表和哈希表
      由链表保证元素有序
      由哈希表保证元素唯一
    |--TreeSet
      底层数据结构是红黑树。
      如何保证元素排序的呢?
        自然排序(元素具备比较性),让元素所属的类实现Comparable接口
        比较器排序(集合具备比较性),让集合接收一个Comparator的实现类对象
      如何保证元素唯一性的呢?
        根据比较的返回值是否是0来决定

3. 针对集合我们到底使用谁呢?

是否是键值对象形式:
  是:Map
    键是否需要排序:
      是:TreeMap
      否:HashMap
    不知道,就使用HashMap。

  否:Collection
    元素是否唯一:
      是:Set
        元素是否需要排序:
          是:TreeSet
          否:HashSet
        不知道,就使用HashSet
      否:List
        要安全吗:
          是:Vector(其实我们也不用它,后面我们讲解了多线程以后,我在给你回顾用谁)
          否:ArrayList或者LinkedList
            增删多:LinkedList
            查询多:ArrayList
          不知道,就使用ArrayList
    不知道,就使用ArrayList

4. 在集合中常见的数据结构
ArrayXxx:底层数据结构是数组,查询快,增删慢
LinkedXxx:底层数据结构是链表,查询慢,增删快
HashXxx:底层数据结构是哈希表。依赖两个方法:hashCode()和equals()
TreeXxx:底层数据结构是二叉树。两种方式排序:自然排序和比较器排序

5. Map
(1) 将键映射到值的对象。一个映射不能包含重复的键;每个键最多只能映射到一个值。
(2) Map和Collection的区别?
  A:Map 存储的是键值对形式的元素,键唯一,值可以重复。
  B:Collection 存储的是单独出现的元素,子接口Set元素唯一,子接口List元素可重复。
  C:Map集合的数据结构值针对键有效,跟值无关,Collection集合的数据结构是针对元素有效。
(3) Map接口功能概述
  A:添加功能 V put(K key,V value)
  B:删除功能 V remove(Object key)
  C:判断功能 boolean containsKey(Object key) / boolean containsValue(Object value) / boolean isEmpty()
  D:获取功能 V get(Object key)
  E:长度功能 int size()
  F:遍历相关功能 Set<K> keySet() / Set<Map.Entry<K,V>> entrySet() / Collection<V> values()
(4) Map接口的实现
  A:HashMap
    基于哈希表的Map接口实现。哈希表的作用是用来保证键的唯一性的。
  B:LinkedHashMap
    是Map接口的哈希表和链接列表实现,具有可预知的迭代顺序。
    由哈希表保证键的唯一性,由链表保证键盘的有序(存储和取出的顺序一致)
  C:TreeMapTreeMap
    基于红黑树的Map接口的实现
(5) Map集合的遍历
  A:键找值
    a:获取所有键的集合
    b:遍历键的集合,得到每一个键
    c:根据键到集合中去找值
  B:键值对对象找键和值
    a:获取所有的键值对对象的集合
    b:遍历键值对对象的集合,获取每一个键值对对象
    c:根据键值对对象去获取键和值

代码体现:

Map<String,String> hm = new HashMap<String,String>();

hm.put("it002","hello");
hm.put("it003","world");
hm.put("it001","java");

//方式1 键找值
Set<String> set = hm.keySet();
for(String key : set) {
    String value = hm.get(key);
    System.out.println(key+"---"+value);
}

//方式2 键值对对象找键和值
Set<Map.Entry<String,String>> set2 = hm.entrySet();
for(Map.Entry<String,String> me : set2) {
    String key = me.getKey();
    String value = me.getValue();
    System.out.println(key+"---"+value);
}

(6) 思考题
  A:HashMap和HashTable的区别
    a:Hashtable:线程安全,效率低。不允许null键和null值
    b:HashMap:线程不安全,效率高。允许null键和null值
    c:HashMap提供了可供应用迭代的键的集合,因此,HashMap是快速失败的。另一方面,Hashtable提供了对键的列举(Enumeration)。
  B:List,Set,Map等接口是否都继承子Map接口?
    List,Set不是继承自Map接口,它们继承自Collection接口
    Map接口本身就是一个顶层接口
  C:如何权衡是使用无序的数组还是有序的数组
    有序数组最大的好处在于查找的时间复杂度是O(log n),而无序数组是O(n)
    有序数组的缺点是插入操作的时间复杂度是O(n),因为值大的元素需要往后移动来给新元素腾位置。相反,无序数组的插入时间复杂度是常量O(1)
  D:HashSet和TreeSet有什么区别
    HashSet是由一个hash表来实现的,因此,它的元素是无序的。add(),remove(),contains()方法的时间复杂度是O(1)。
    另一方面,**TreeSet是由一个树形的结构来实现的,它里面的元素是有序的。**因此,add(),remove(),contains()方法的时间复杂度是O(logn)。
  E:为什么集合类没有实现Cloneable和Serializable接口?
    克隆(cloning)或者是序列化(serialization)的语义和含义是跟具体的实现相关的。因此,应该由集合类的具体实现来决定如何被克隆或者是序列化。
    实现Serializable序列化的作用
      1. 将对象的状态保存在存储媒体中以便可以在以后重写创建出完全相同的副本;
      2. 按值将对象从一个从一个应用程序域发向另一个应用程序域。
    实现 Serializable接口的作用就是可以把对象存到字节流,然后可以恢复。所以你想如果你的对象没有序列化,怎么才能进行网络传输呢?
    要网络传输就得转为字节流,所以在分布式应用中,你就得实现序列化。如果你不需要分布式应用,那就没必要实现实现序列化。
    分布式应用:例如Hadoop大数据平台等多台机子组成一个集群,多个机子共同执行一个任务的情况。
(7) HashMap的工作原理
  Java中的HashMap是以键值对(key-value)的形式存储元素的。
  HashMap需要一个hash函数,它使用hashCode()和equals()方法来向集合/从集合添加和检索元素。
  当调用put()方法的时候,HashMap会计算key的hash值,然后把键值对存储在集合中合适的索引上。
  如果key已经存在了,value会被更新成新值。
  HashMap的一些重要的特性是它的容量(capacity),负载因子(load factor)和扩容极限(threshold resizing)。

6. Collections
(1) 是针对集合进行操作的工具类
(2) 思考题:Collection和Collections的区别
  A:Collection 是单列集合的顶层接口,有两个子接口List和Set
  B:Collections 是针对集合进行操作的工具类,可以对集合进行排序和查找等
(3) 常见的几个小方法:
  A:public static <T> void sort(List<T> list):排序 默认情况下是自然顺序。
  B:public static <T> int binarySearch(List<?> list,T key):二分查找
  C:public static <T> T max(Collection<?> coll):最大值
  D:public static void reverse(List<?> list):反转
  E:public static void shuffle(List<?> list):随机置换

posted @ 2019-10-21 15:29  brynchen  阅读(158)  评论(0)    收藏  举报