----------------------集合-------------------------

             

1:集合:存储对象  遍历取出对象

List<要存储元素的数据类型> 变量名 = new ArrayList<要存储元素的数据类型>();

必须要引用数据类型,不能是基本类型,除非把基本数据类型变成包装类

b:集合
* b1:集合的层次结构
* Iterable <E> 实现了Iterable接口的集合类才可以被foreach
* Collection  接口  集合最顶层的接口
* List   接口特点:   有序   有索引   可以重复元素     元素存与取的顺序相同

泛型用来约束集合中可有存储的数据类型
* ArrayList 底层是数组 根据索引查询,增删慢    ArrayList是实现了基于动态数组的数据结构 寻址容易,插入和删除困难; 
* LinkedList 底层是链表   增删快  查询慢 LinkedList是基于链表的数据结构 寻址困难,插入和删除容易。  子类特有的功能,不能多态调用
* Stack 栈结构的集合   stack继承vector其底层用的还是数组存储方式         

   Stack 栈结构的集合       官方建议:使用栈尽量使用ArrayDeque:

Deque 接口及其实现提供了 LIFO 堆栈操作的更完整和更一致的 set,应该优先使用此 set,而非此类。例如:

Deque stack = new ArrayDeque();


* Vector 线程安全的线性集合

**Vector集合数据存储的结构是数组结构,为JDK中最早提供的集合。Vector中提供了一个独特的取出方式,就是枚举Enumeration,它其实就是早期的迭代器。此接口Enumeration的功能与 Iterator 接口的功能是类似的。Vector集合已被ArrayList替代。枚举Enumeration已被迭代器Iterator替代。

2.0 HashSet集合存储数据的结构(哈希表)

什么是哈希表呢?

哈希表底层使用的也是数组机制,数组中也存放对象,而这些对象往数组中存放时的位置比较特殊,当需要把这些对象给数组中存放时,那么会根据这些对象的特有数据结合相应的算法,计算出这个对象在数组中的位置,然后把这个对象存放在数组中。而这样的数组就称为哈希数组,即就是哈希表。

当向哈希表中存放元素时,需要根据元素的特有数据结合相应的算法,这个算法其实就是Object类中的hashCode方法。由于任何对象都是Object类的子类,所以任何对象有拥有这个方法。即就是在给哈希表中存放对象时,会调用对象的hashCode方法,算出对象在表中的存放位置,这里需要注意,如果两个对象hashCode方法算出结果一样,这样现象称为哈希冲突,这时会调用对象的equals方法,比较这两个对象是不是同一个对象,如果equals方法返回的是true,那么就不会把第二个对象存放在哈希表中,如果返回的是false,就会把这个值存放在哈希表中。

总结:保证HashSet集合元素的唯一,其实就是根据对象的hashCode和equals方法来决定的。如果我们往集合中存放自定义的对象,那么保证其唯一,就必须复写hashCode和equals方法建立属于当前对象的比较方式。

Set 无序不可重复   set集合可以存储多个对象,但并不会记住元素的存储顺序,也不允许集合中有重复元素(不同的set集合有不同的判断方法)。    元素存与取的顺序可能不同

*hashSet  底层是哈希表

*TreeSet   TreeSet 底层实际使用的存储容器就是 TreeMap    TreeMap 的实现就是红黑树数据结构

* eg:
* hashset底层是使用什么实现的?
* 底层数据结构是哈希表,哈希表就是存储唯一系列的表,而哈希值是由对象的hashCode()方法生成。
* hashset中元素是唯一的 为什么是唯一的?它是如何实现的?    

* 确保唯一性的两个方法:hashCode()和equals()方法。

HashSet按照Hash算法存储集合中的元素,具有很好的存取和查找性能。当向HashSet中添加一些元素时,HashSet会根据该对象的HashCode()方法来得到该对象的HashCode值,然后根据这些HashCode的值来决定元素的位置。

TreeSet支持两种排序方法:自然排序和定制排序。在默认的情况下,TreeSet采用自然排序。

自然排序:TreeSet会调用集合元素的compareTo(Object obj)方法来比较元素之间的大小关系,然后让集合按照升序排列,这种方式叫做自然排序。

定制排序:定制排序是按照使用者的要求,需要自己设计的一种排序。如果需要定制排序,比如需要数据按照降序排列,则可以通过Comparator接口的帮助。

PS:

1.如果希望TreeSet能够正常运行,TreeSet只能添加同一种类型的对象。

2.TreeSet集合中判断元素相等的唯一标准是:两个对象通过comparator(Object obj)方法比较后,返回0;否则认为不相等。

Map
* HashMap ---------丨 HashMap的遍历速度和他的容量有关。不自动同步
* Hashtable -------丨 都实现了Map接口,它继承自Dictionary类 Hashtable线程安全, HashMap线程不安全
* LinkedHashMap LinkedHashMap的遍历速度只和他的数据有关。  LinkedHashMap实现类使用链表来维护key-value的次序,可以记住键值对的插入顺序
* TreeMap 实现SortMap接口,能够把它保存的记录根据键排序,默认是按键值的升序排序   TreeMap底层采用红黑树来管理key-value对

TreeMap存储key-value键值对时,需要根据key对节点进行排序。TreeMap可以保证所有的key-value对处于有序状态。也有两种排序方式:

  1)  自然排序:TreeMap的所有key必须实现Comparable接口,而且所有的key应该是同一个类的对象,否则抛出ClassCastException异常。

  2)  定制排序:创建TreeMap时,传入一个Comparator对象,该对象负责对TreeMap中的所有key进行排序。不需要Map的key实现Comparable接口。

* hashmap底层是什么结构?如何保证key是唯一的?请解释
* 数组+链表(维护了一张 HashTable ) 每一个被添加的元素都有一个 hashCode(哈希值),他们先比较哈希值,是否相同?
* 不相同的元素,添加进入 HashTable. 如果hashCode相同的话, 再去比较 equals()方法,
* 如果也相同的话,JVM就认为数据已经存在了,就不会添加数据!

hashtable和hashmap的区别:

hashtable 有同步机制  接受值为null的Key 或Value

hashmap  没有同步机制,需要使用者自己进行并发访问控制    接受值为null的Key 或Value

* b2:b1中提到的每种集合类的常用方法需要熟练使用
* b3:b1中提到的每种集合类的底层结构都需要清晰
* 可以从原理角度解释每种集合类的特点

例 1

在使用 List 集合时需要注意区分 indexOf() 方法和 lastIndexOf() 方法。前者是获得指定对象的最小索引位置,而后者是获得指定对象的最大索引位置。前提条件是指定的对象在 List 集合中有重复的对象,否则这两个方法获取的索引值相同。

下面的案例代码演示了 indexOf() 方法和 lastIndexOf() 方法的区别。

  1. public static void main(String[] args)
  2. {
  3. List list=new ArrayList();
  4. list.add("One");
  5. list.add("|");
  6. list.add("Two");
  7. list.add("|");
  8. list.add("Three");
  9. list.add("|");
  10. list.add("Four");
  11. System.out.println("list 集合中的元素数量:"+list.size());
  12. System.out.println("list 集合中的元素如下:");
  13. Iterator it=list.iterator();
  14. while(it.hasNext())
  15. {
  16. System.out.print(it.next()+"、");
  17. }
  18. System.out.println(" 在 list 集合中'丨'第一次出现的位置是:"+list.indexOf("|"));
  19. System.out.println("在 list 集合中'丨'最后一次出现的位置是:"+list.lastIndexOf("|"));
  20. }


上述代码创建一个 List 集合 list,然后添加了 7 个元素,由于索引从 0 开始,所以最后一个元素的索引为 6。输出结果如下:

list 集合中的元素数量:7
list 集合中的元素如下:
One、|、Two、|、Three、|、Four、
在 list 集合中'|'第一次出现的位置是:1
在 list 集合中'|'最后一次出现的位置是:5

例 2

在仓库管理系统中要记录入库的商品名称,并且需要输出第一个录入的商品名称和最后—个商品名称。下面使用 LinkedList 集合来完成这些功能,实现代码如下:
  1. public static void main(String[] args)
  2. {
  3. LinkedList<String> products=new LinkedList<String>(); //创建集合对象
  4. String p1=new String("六角螺母");
  5. String p2=new String("10A 电缆线");
  6. String p3=new String("5M 卷尺");
  7. String p4=new String("4CM 原木方板");
  8. products.add(p1); //将 pi 对象添加到 LinkedList 集合中
  9. products.add(p2); //将 p2 对象添加到 LinkedList 集合中
  10. products.add(p3); //将 p3 对象添加到 LinkedList 集合中
  11. products.add(p4); //将 p4 对象添加到 LinkedList 集合中
  12. String p5=new String("标准文件夹小柜");
  13. products.addLast(p5); //向集合的末尾添加p5对象
  14. System.out.print("*************** 商品信息 ***************");
  15. System.out.println(" 目前商品有:");
  16. for(int i=0;i<products.size();i++)
  17. {
  18. System.out.print(products.get(i)+" ");
  19. }
  20. System.out.println(" 第一个商品的名称为:"+products.getFirst());
  21. System.out.println("最后一个商品的名称为:"+products.getLast());
  22. products.removeLast(); //删除最后一个元素
  23. System.out.println("删除最后的元素,目前商品有:");
  24. for(int i=0;i<products.size();i++)
  25. {
  26. System.out.print(products.get(i)+" ");
  27. }
  28. }

如上述代码,首先创建了 5 个 String 对象,分别为 p1、p2、p3、p4 和 p5。同时将 pl、 p2、p3 和 p4 对象使用 add() 方法添加到 LinkedList 集合中,使用 addLast() 方法将 p5 对象添加到 LinkedList 集合中。分别调用 LinkedList 类中的 getFirst() 方法和 getLast()方法获取第一个和最后一个商品名称。最后使用 removeLast() 方法将最后一个商品信息删除,并将剩余商品信息打印出来。

LinkedList<String> 中的 <String> 是 Java 中的泛型,用于指定集合中元素的数据类型,例如这里指定元素类型为 String,则该集合中不能添加非 String 类型的元素。

运行程序,执行结果如下:
*************** 商品信息 ***************
目前商品有:
六角螺母    10A 电缆线    5M 卷尺    4CM 原木方板    标准文件夹小柜   
第一个商品的名称为:六角螺母
最后一个商品的名称为:标准文件夹小柜
删除最后的元素,目前商品有:
六角螺母    10A 电缆线    5M 卷尺    4CM 原木方板



原文地址:https://www.cnblogs.com/helloaugust/p/10980492.html