zoukankan      html  css  js  c++  java
  • 集合

    1.1 为什么要使用集合框架?

    传统的容器(数组)进行增、删破坏性操作时,需要移动元素,可能导致性能问题同时添加、删除等算法和具体业务耦合在一起,增加了程序开发的复杂度。 

    Java集合框架提供了一套性能优良、使用方便的接口和类,它们位于java.util包中

    1.2 Collection

    Collectionjava集合框架(collection-frame)的顶层接口。

    Collection接口表示一个容器,容器中只能存储引用数据类型建议存同一类型的引用类型,方便后续遍历等操作。

    容器中的元素可以是有序的可重复的,为List接口

    也可能是无序的、唯一的称为Set接口。

     

    1.2.1 集合常用方法

     1 public static void main(String[] args) {
     2 
     3  
     4 
     5 /**
     6 
     7  * 增:add/addAll
     8 
     9  * 删:clear/remove/removeAll/retainAll
    10 
    11  * 改:
    12 
    13  * 查:contains/containsAll/isEmpty/size
    14 
    15  */
    16 
    17  
    18 
    19 Collection c1 = new ArrayList();
    20 
    21  
    22 
    23 // 追加
    24 
    25 c1.add("apple"); // Object object = new String("apple");
    26 
    27 // c1.add(1);  // Object object = new Integer(1);
    28 
    29 c1.add("banana");
    30 
    31 System.out.println(c1);
    32 
    33  
    34 
    35 // 追加一个集合
    36 
    37 Collection c2 = new ArrayList();
    38 
    39 c2.add("java");
    40 
    41 c2.add("c++");
    42 
    43 c1.addAll(c2);
    44 
    45 System.out.println(c1);
    46 
    47  
    48 
    49 // clear
    50 
    51 //c1.clear();
    52 
    53  
    54 
    55 // c1.remove("apple");
    56 
    57 // c1.removeAll(c2);
    58 
    59 //c1.retainAll(c2);
    60 
    61 //System.out.println(c1);
    62 
    63  
    64 
    65 System.out.println(c1.contains("apple"));
    66 
    67 c2.add("js");
    68 
    69 System.out.println(c1.containsAll(c2));
    70 
    71 // c1.clear();
    72 
    73 System.out.println(c1.isEmpty());
    74 
    75 // 返回集合元素的个数
    76 
    77 System.out.println(c1.size());
    78 
    79  
    80 
    81 System.out.println(c1.equals(c2));
    82 
    83  
    84 
    85 }

    1.2.2 集合的遍历 

    Iterable 可遍历的接口,集合接口继承于它,集合支持快速遍历。

     1 // 快速遍历
     2 
     3 // for-each
     4 
     5 // Object 表示元素类型
     6 
     7 // item表示迭代变量
     8 
     9 // c1表示集合
    10 
    11 for (Object item : c1) {
    12 
    13 System.out.println(item.toString());
    14 
    15 }

    快速遍历的本质

    Collection继承Iterable接口,表示集合支持快速遍历。Iterable接口定义了一个方法iterator()用于获取集合的迭代器,是一个Iterator接口类型,iterator()内部返回一个实现类实现类Iterator接口这个实现类一定具有hasNextnext方法用于判断是否有下一个元素和获取下一个元素。快速遍历就是基于迭代器工作的。

     1 public static void main(String[] args) {
     2 
     3  
     4 
     5  
     6 
     7 Collection c1 = new ArrayList();
     8 
     9 c1.add("apple");
    10 
    11 c1.add("banana");
    12 
    13 c1.add("coco");
    14 
    15  
    16 
    17  
    18 
    19 // 快速遍历
    20 
    21 // for-each
    22 
    23 // Object 表示元素类型
    24 
    25 // item表示迭代变量
    26 
    27 // c1表示集合
    28 
    29 for (Object item : c1) {
    30 
    31 System.out.println(item.toString());
    32 
    33 }
    34 
    35  
    36 
    37 // 迭代器遍历(国内)
    38 
    39 Iterator it = c1.iterator();
    40 
    41 while(it.hasNext()) {
    42 
    43 Object item = it.next();
    44 
    45 System.out.println(item.toString());
    46 
    47 }
    48 
    49  
    50 
    51 // 国外
    52 
    53 for(Iterator it2=c1.iterator();it2.hasNext();) {
    54 
    55 Object item = it2.next();
    56 
    57 System.out.println(item.toString());
    58 
    59 }
    60 
    61 }

    1.3 List接口

    List 接口中的元素时有序的、可重复的。List接口的元素通过索引(index)确定元素的顺序。

    有序的 collection(也称为序列)。可以对列表中每个元素的插入位置进行精确地控制。用户可以根据元素的整数索引(在列表中的位置)访问元素,并搜索列表中的元素 

    1.3.1 List常用方法

     1 public static void main(String[] args) {
     2 
     3  
     4 
     5 /**
     6 
     7  * 增:add/addAll/add(index,el)/addAll(index,collection)
     8 
     9  * 删:clear/remove/removeAll/remove(index)
    10 
    11  * 改:set(index,el)
    12 
    13  * 查:get(index)/indexOf/lastIndexOf()
    14 
    15  * 其他:contains/containsAll/isEmpty/size
    16 
    17  */
    18 
    19 List list1 = new ArrayList();
    20 
    21 // 添加元素
    22 
    23 list1.add("apple");
    24 
    25 list1.add("banana");
    26 
    27 // 在指定位置添加元素
    28 
    29 list1.add(0, "coco");
    30 
    31  
    32 
    33 System.out.println(list1);
    34 
    35  
    36 
    37 List list2 = new ArrayList();
    38 
    39 list2.add("java");
    40 
    41 list2.add("c++");
    42 
    43  
    44 
    45 list1.addAll(1, list2);
    46 
    47 System.out.println(list1);
    48 
    49  
    50 
    51 // 删除
    52 
    53 list1.remove(0);
    54 
    55 System.out.println(list1);
    56 
    57  
    58 
    59 // 修改
    60 
    61 list1.set(0, "javax");
    62 
    63 System.out.println(list1);
    64 
    65  
    66 
    67 //
    68 
    69 System.out.println(list1.get(0));
    70 
    71 list1.add("apple");
    72 
    73 list1.add("apple");
    74 
    75 System.out.println(list1);
    76 
    77 System.out.println(list1.indexOf("apple"));
    78 
    79 System.out.println(list1.lastIndexOf("apple"));
    80 
    81 }

    1.3.2 List接口遍历 

    ListIterator 继承Iterator,在Iterator基础上提供了以正向遍历集合,也可以以逆序遍历集合。

    hasNext/next 以正向遍历

    hasPrevious/previous 以逆序遍历

     1 public static void main(String[] args) {
     2 
     3  
     4 
     5  
     6 
     7 List list1 = new ArrayList();
     8 
     9 list1.add("apple");
    10 
    11 list1.add("banana");
    12 
    13 list1.add("coco");
    14 
    15  
    16 
    17 // 【1】快速遍历
    18 
    19 System.out.println("--for each--");
    20 
    21 for (Object item : list1) {
    22 
    23 System.out.println(item.toString());
    24 
    25 }
    26 
    27  
    28 
    29 // 【2】普通for
    30 
    31 System.out.println("--for--");
    32 
    33 for(int i=0;i<list1.size();i++) {
    34 
    35 System.out.println(list1.get(i));
    36 
    37 }
    38 
    39  
    40 
    41 // 【3】集合迭代器
    42 
    43 System.out.println("--iterator--");
    44 
    45 Iterator it = list1.iterator();
    46 
    47 while(it.hasNext()) {
    48 
    49 System.out.println(it.next());
    50 
    51 }
    52 
    53  
    54 
    55 System.out.println("--list iterator--");
    56 
    57 // 正向遍历
    58 
    59 ListIterator it2 = list1.listIterator();
    60 
    61 while(it2.hasNext()) {
    62 
    63 System.out.println(it2.next());
    64 
    65 }
    66 
    67  
    68 
    69 // 逆序遍历
    70 
    71 while(it2.hasPrevious()) {
    72 
    73 System.out.println(it2.previous());
    74 
    75 }
    76 
    77  
    78 
    79 System.out.println("--list iterator with index--");
    80 
    81 ListIterator it3 = list1.listIterator(1);
    82 
    83 while(it3.hasNext()) {
    84 
    85 System.out.println(it3.next());
    86 
    87 }
    88 
    89 }

    1.4 数据结构(补充) 

    数据结构就是数据在内存中存储结构。根据存储的方式不同,分为线性表、二叉树、图、栈、队列等

    1.4.1 线性

    线性表数据按照一定的逻辑顺序存储在内存中。线性表是有序的。线性表根据内存的物理结构分为两种:数组和链表

    数组是一种逻辑上有序的线性表,物理上也连续

    链表是一种逻辑上有序的线性表,但物理上不连续。

    数组和链表的区别 

    相同点:逻辑上有序的线性表

    不同点:

    数组在查询时效率高,在添加、删除元素时效率低(涉及移动元素)

    链表在查询时效率(每次从头开始不能跳跃访问),在添加、删除元素时效率高(不涉及移动元素)

    1.4.2 

    特性:进后出,后进先出

    1.4.3 队列 

    特性:进先出

      

    1.5 ArrayList/Vector

    ArrayList List接口的实现类,底层数据结构是数组实现大小可变的数组。

    ArrayList 线程不安全,jdk1.2

    ArrayList 底层数据结构是数组,默认数组大小是10,如果添加的元素个数超过默认容量,ArrayList会自动拓容,拓容原则:newCapacity = oldCapacity + oldCapacity / 2;

    如果未来确定序列的元素不在增加,通过调用trimToSize()调制容量至合适的空间。

    ArrayList作为List接口的实现类,常用方法和遍历方法参考List接口。

    Vector 是List的实现类,底层数据结构也是数组,也是大小可变的数组

    Vector是线程安全的,jdk1.0

    Vector底层数据结构是数组,默认数组大小是10,如果添加的元素个数超过默认容量,Vector会自动拓容,拓容原则:newCapacity = oldCapacity +capacityIncrement(增长因子);如果未来确定序列的元素不在增加,通过调用trimToSize()调制容量至合适的空间。

    注意:Vector 实现List接口的同时,同添加了自身特有的方法xxxElement,未来使用时为了程序的可拓展性,一定要按照接口来操作Vector

    1.6 LinkedList

    LinkedListList接口的实现类,底层数据结构是链表。

    LinekList常用方法和遍历方法参照List接口

    LinkedList 线程不安全

    了实现List接口, 实现栈接口

    push入栈操作 / pop出栈操作

     1 public class Test01 {
     2 
     3 public static void main(String[] args) {
     4 
     5 LinkedList list = new LinkedList();
     6 
     7 list.push("apple");
     8 
     9 list.push("banana");
    10 
    11 list.push("coco");
    12 
    13  
    14 
    15  
    16 
    17 System.out.println(list.pop());
    18 
    19 System.out.println(list.pop());
    20 
    21 System.out.println(list.pop());
    22 
    23  
    24 
    25 // java.util.NoSuchElementException
    26 
    27 System.out.println(list.pop());
    28 
    29 }
    30 
    31 }

    队列(Queue)接口

    add/remove/element() 可能会出现NoSuchElementException异常 

     1 public static void main(String[] args) {
     2 
     3  
     4 
     5 LinkedList queue = new LinkedList();
     6 
     7 // 入队
     8 
     9 /**
    10 
    11  * 队列头                   队列尾
    12 
    13  *<-----          <-----
    14 
    15  * [apple, banana, coco]
    16 
    17  */
    18 
    19 queue.add("apple");
    20 
    21 queue.add("banana");
    22 
    23 queue.add("coco");
    24 
    25 System.out.println(queue);
    26 
    27  
    28 
    29 // 出队
    30 
    31 System.out.println(queue.remove());
    32 
    33 System.out.println(queue.remove());
    34 
    35 System.out.println(queue.remove());
    36 
    37 System.out.println(queue);
    38 
    39  
    40 
    41 // java.util.NoSuchElementException
    42 
    43 System.out.println(queue.remove());
    44 
    45  
    46 
    47  
    48 
    49 // 获取表头元素
    50 
    51 System.out.println(queue.element());
    52 
    53 }

    offer/poll/peek 可能会返回特殊值(null) 

     1 public static void main(String[] args) {
     2 
     3  
     4 
     5 LinkedList queue = new LinkedList();
     6 
     7 // 入队
     8 
     9 /**
    10 
    11  * 队列头                   队列尾
    12 
    13  *<-----          <-----
    14 
    15  * [apple, banana, coco]
    16 
    17  */
    18 
    19 queue.offer("apple");
    20 
    21 queue.offer("banana");
    22 
    23 queue.offer("coco");
    24 
    25  
    26 
    27 // 出队列
    28 
    29 //System.out.println(queue.poll());
    30 
    31 //System.out.println(queue.poll());
    32 
    33 //System.out.println(queue.poll());
    34 
    35 System.out.println(queue);
    36 
    37  
    38 
    39 //System.out.println(queue.poll());
    40 
    41  
    42 
    43 // 获取表头元素
    44 
    45 System.out.println(queue.peek());
    46 
    47  
    48 
    49 }

    双向队列(Deque)接口

     1 /**
     2 
     3  * 以双向队列形式操作LinkedList
     4 
     5  */
     6 
     7 public class Test04 {
     8 
     9 public static void main(String[] args) {
    10 
    11  
    12 
    13 LinkedList queue = new LinkedList();
    14 
    15 // 入队
    16 
    17 /**
    18 
    19  *<-----          <-----
    20 
    21  * [apple, banana, coco]
    22 
    23  * ---->          ----->
    24 
    25  */
    26 
    27  
    28 
    29 queue.addFirst("apple");
    30 
    31 queue.addFirst("banana");
    32 
    33 queue.addFirst("coco");
    34 
    35 System.out.println(queue);
    36 
    37  
    38 
    39 System.out.println(queue.removeLast());
    40 
    41 System.out.println(queue.removeFirst());
    42 
    43 System.out.println(queue.removeFirst());
    44 
    45 System.out.println(queue);
    46 
    47  
    48 
    49 // 获取头元素
    50 
    51 System.out.println(queue.getFirst());
    52 
    53  
    54 
    55 }
    56 
    57 }  

    1.7 IteratorListIterator

    Iterator迭代过程中不允许向集合中添加元素

     1 public static void main(String[] args) {
     2 
     3 ArrayList list = new ArrayList();
     4 
     5 list.add("apple");
     6 
     7 list.add("banana");
     8 
     9 list.add("coco");
    10 
    11  
    12 
    13 Iterator it = list.iterator();
    14 
    15 while(it.hasNext()) {
    16 
    17 String item = (String) it.next();
    18 
    19 if(item.equals("banana")) {
    20 
    21 list.add("test");
    22 
    23 }
    24 
    25 }
    26 
    27  
    28 
    29 System.out.println(list);
    30 
    31 }

     当通过Iterator集合迭代器遍历集合过程中,不能再向集合汇总添加元素否则出现ConcurrentModificationException 并发修改异常。

    ListIterator允许程序员按任一方向遍历列表、迭代期间修改列表,并获得迭代器在列表中的当前位置

     1 public class Test01 {
     2 
     3 public static void main(String[] args) {
     4 
     5 ArrayList list = new ArrayList();
     6 
     7 list.add("apple");
     8 
     9 list.add("banana");
    10 
    11 list.add("coco");
    12 
    13  
    14 
    15 ListIterator it = list.listIterator();
    16 
    17 while(it.hasNext()) {
    18 
    19 String item = (String) it.next();
    20 
    21 if(item.equals("banana")) {
    22 
    23 it.add("test");
    24 
    25 }
    26 
    27 }
    28 
    29  
    30 
    31 System.out.println(list);
    32 
    33 }
    34 
    35 }

     

  • 相关阅读:
    SQL Server 中的事务与事务隔离级别以及如何理解脏读, 未提交读,不可重复读和幻读产生的过程和原因
    微软BI 之SSIS 系列
    微软BI 之SSIS 系列
    微软BI 之SSIS 系列
    微软BI 之SSIS 系列
    微软BI 之SSIS 系列
    微软BI 之SSAS 系列
    微软BI 之SSRS 系列
    微软BI 之SSRS 系列
    配置 SQL Server Email 发送以及 Job 的 Notification通知功能
  • 原文地址:https://www.cnblogs.com/ruckly/p/10817222.html
Copyright © 2011-2022 走看看