zoukankan      html  css  js  c++  java
  • Java基础知识笔记(八:集合类)

    目录

    1  集合类简介 

    2  List介绍及简单使用 

    2.1  LinkedList介绍及简单使用 

    2.2  ArrayList介绍及简单使用 

    2.3  Vector介绍及简单使用

    2.3.1  Stack介绍及简单使用 

    3  Set介绍 

    3.1 HashSet介绍及简单使用 

    3.2 TreeSet介绍及简单使用 

    3.3 Linked HashSet介绍 

    4  Map介绍及简单使用 

    4.1 Hashtable介绍及简单使用 

    4.2 HashMap简单使用 

    4.3 WeakHashMap介绍 


    1  集合类简介

    集合类存放于java.util包中。

    集合类存放的都是对象的引用,而非对象本身,出于表达上的便利,我们称集合中的对象就是指集合中对象的引用(reference)

    集合类型主要有3种:list(集)、set(列表)和map(映射)

    具体关系如下:

    Collection
    List
    ├LinkedList
    ├ArrayList
    └Vector
     └Stack

    Set

    ├HashSet
    ├TreeSet
    └Linked HashSet

    Map
    ├Hashtable
    ├HashMap
    └WeakHashMap

        Collection是最基本的集合接口,一个Collection代表一组Object,即Collection的元素(Elements)。一些Collection允许相同的元素而另一些不行。一些能排序而另一些不行。Java SDK不提供直接继承自Collection类,Java SDK提供的类都是继承自Collection子接口ListSet
      所有实现Collection接口的类都必须提供两个标准的构造函数:无参数的构造函数用于创建一个空的Collection,有一个 Collection参数的构造函数用于创建一个新的Collection这个新的Collection与传入的Collection有相同的元素。后一个构造函数允许用户复制一个Collection
      如何遍历Collection中的每一个元素?不论Collection的实际类型如何,它都支持一个iterator()的方法,该方法返回一个迭代子,使用该迭代子即可逐一访问Collection中每一个元素。典型的用法如下:
        Iterator it = collection.iterator(); // 获得一个迭代子
        while(it.hasNext()) {
          Object obj = it.next(); // 得到下一个元素
        }


    2  List介绍及简单使用

    介绍:List是有序的Collection,使用此接口能够精确的控制每个元素插入的位置。用户能够使用索引(元素在List中的位置,类似于数组下标)来访问List中的元素,这类似于Java的数组。和下面要提到的Set不同,List允许有相同的元素。
      除了具有Collection接口必备的iterator()方法外,List还提供一个listIterator()方法,返回一个 ListIterator接口,和标准的Iterator接口相比,ListIterator多了一些add()之类的方法,允许添加,删除,设定元素, 还能向前或向后遍历。
      实现List接口的常用类有LinkedListArrayListVectorStack

    实例查找 List 中的最大最小值

    以下实例演示了如何使用 Collections类的 max() 和 min() 方法来获取List中最大最小值:

    import java.util.*;
    public class Main {
       public static void main(String[] args) {
          List list = Arrays.asList("one Two three Four five six one three Four".split(" "));
          System.out.println(list);
          System.out.println("最大值: " + Collections.max(list));
          System.out.println("最小值: " + Collections.min(list));
       }}

    以上代码运行输出结果为:

    [one, Two, three, Four, five, six, one, three, Four]
    最大值: three
    最小值: Four

    2.1  LinkedList介绍及简单使用

    介绍:LinkedList类是双向列表,列表中的每个节点都包含了对前一个和后一个元素的引用.
    LinkedList的构造函数如下
    1. public LinkedList():  ——生成空的链表
    2. public LinkedList(Collection col):  复制构造函数
    实例获取链表的第一个和最后一个元素

    import java.util.LinkedList;  
      
    public class LinkedListTest{  
        public static void main(String[] args) {  
          LinkedList<String> lList = new LinkedList<String>();  
          lList.add("1");  
          lList.add("2");  
          lList.add("3");  
          lList.add("4");  
          lList.add("5");  
      
      
          System.out.println("链表的第一个元素是 : " + lList.getFirst());  
          System.out.println("链表最后一个元素是 : " + lList.getLast());  
       }  
    }  

    2.2  ArrayList介绍及简单使用

    介绍:ArrayList就是传说中的动态数组,换种说法,就是Array的复杂版本,它提供了如下一些好处: 
    动态的增加和减少元素 
    实现了ICollectionIList接口 
    灵活的设置数组的大小

     实例

    ArrayList List = new ArrayList(); 
    for( int i=0;i <10;i++ ) //给数组增加10个Int元素 
    List.Add(i); 
    //..程序做一些处理 
    List.RemoveAt(5);//将第6个元素移除 
    for( int i=0;i <3;i++ ) //再增加3个元素 
    List.Add(i+20); 
    Int32[] values = (Int32[])List.ToArray(typeof(Int32));//返回ArrayList包含的数组

    2.3  Vector介绍及简单使用

    介绍:

    Vector类实现了一个动态数组。和ArrayList和相似,但是两者是不同的:

    Vector是同步访问的。

    Vector包含了许多传统的方法,这些方法不属于集合框架。

    Vector主要用在事先不知道数组的大小,或者只是需要一个可以改变大小的数组的情况。

    Vector类支持4种构造方法。

    第一种构造方法创建一个默认的向量,默认大小为10

    Vector()

    第二种构造方法创建指定大小的向量。

    Vector(int size)

    第三种构造方法创建指定大小的向量,并且增量用incr指定. 增量表示向量每次增加的元素数目。

    Vector(int size,int incr)

    第四中构造方法创建一个包含集合c元素的向量:

    Vector(Collection c)

    实例

    import java.util.*;
    public class VectorDemo {
    
       public static void main(String args[]) {
          // initial size is 3, increment is 2
          Vector v = new Vector(3, 2);
          System.out.println("Initial size: " + v.size());
          System.out.println("Initial capacity: " +
          v.capacity());
          v.addElement(new Integer(1));
          v.addElement(new Integer(2));
          v.addElement(new Integer(3));
          v.addElement(new Integer(4));
          System.out.println("Capacity after four additions: " +
              v.capacity());
    
          v.addElement(new Double(5.45));
          System.out.println("Current capacity: " +
          v.capacity());
          v.addElement(new Double(6.08));
          v.addElement(new Integer(7));
          System.out.println("Current capacity: " +
          v.capacity());
          v.addElement(new Float(9.4));
          v.addElement(new Integer(10));
          System.out.println("Current capacity: " +
          v.capacity());
          v.addElement(new Integer(11));
          v.addElement(new Integer(12));
          System.out.println("First element: " +
             (Integer)v.firstElement());
          System.out.println("Last element: " +
             (Integer)v.lastElement());
          if(v.contains(new Integer(3)))
             System.out.println("Vector contains 3.");
          // enumerate the elements in the vector.
          Enumeration vEnum = v.elements();
          System.out.println("
    Elements in vector:");
          while(vEnum.hasMoreElements())
             System.out.print(vEnum.nextElement() + " ");
          System.out.println();
       }}

    以上实例编译运行结果如下:

    Initial size: 0
    Initial capacity: 3
    Capacity after four additions: 5
    Current capacity: 5
    Current capacity: 7
    Current capacity: 9
    First element: 1Last element: 12Vector contains 3. Elements in vector:1 2 3 4 5.45 6.08 7 9.4 10 11 12

    2.3.1  Stack介绍及简单使用

    介绍:

    栈是Vector的一个子类,它实现了一个标准的后进先出的栈。 

    堆栈只定义了默认构造函数,用来创建一个空栈。 堆栈除了包括由Vector定义的所有方法,也定义了自己的一些方法。

    Stack()

    除了由Vector定义的所有方法,自己也定义了一些方法:

    序号

    方法描述

    1

    boolean empty() 
    测试堆栈是否为空。

    2

    Object peek( )
    查看堆栈顶部的对象,但不从堆栈中移除它。

    3

    Object pop( )
    移除堆栈顶部的对象,并作为此函数的值返回该对象。

    4

    Object push(Object element)
    把项压入堆栈顶部。

    5

    int search(Object element)
    返回对象在堆栈中的位置,以 1 为基数。

    实例

    下面的程序说明这个集合所支持的几种方法

    import java.util.*;
    public class StackDemo {
    
       static void showpush(Stack st, int a) {
          st.push(new Integer(a));
          System.out.println("push(" + a + ")");
          System.out.println("stack: " + st);
       }
    
       static void showpop(Stack st) {
          System.out.print("pop -> ");
          Integer a = (Integer) st.pop();
          System.out.println(a);
          System.out.println("stack: " + st);
       }
    
       public static void main(String args[]) {
          Stack st = new Stack();
          System.out.println("stack: " + st);
          showpush(st, 42);
          showpush(st, 66);
          showpush(st, 99);
          showpop(st);
          showpop(st);
          showpop(st);
          try {
             showpop(st);
          } catch (EmptyStackException e) {
             System.out.println("empty stack");
          }
       }}

    以上实例编译运行结果如下:

    stack: [ ]
    push(42)
    stack: [42]
    push(66)
    stack: [42, 66]
    push(99)
    stack: [42, 66, 99]
    pop -> 99
    stack: [42, 66]
    pop -> 66
    stack: [42]
    pop -> 42
    stack: [ ]
    pop -> empty stack

     


    3  Set介绍

    介绍: 

        Set不保存重复的元素。Set中最常被使用的是测试归属性,你可以很容易的询问某个对象是否在某个Set中。Set具有与Collection完全一样的接口,因此没有任何额外的功能。实际上Set就是Collection,只是行为不同。

      实现了Set接口的主要有HashSetTreeSetLinkedHashSet这几个共同点就是每个相同的项只保存一份。他们也有不同点,区别如下:

    3.1 HashSet介绍及简单使用

    介绍:

     HashSet使用的是相当复杂的方式来存储元素的,使用HashSet能够最快的获取集合中的元素,效率非常高(以空间换时间)。会根据hashcodeequals来庞端是否是同一个对象,如果hashcode一样,并且equals返回true,则是同一个对象,不能重复存放。

    实例

    package com.set;
    
    import java.util.HashSet;
    import java.util.Set;
    
    class Student{
        int id;
        public Student(int id) {
            this.id = id;
        }
        @Override
        public String toString() {
            return this.id+"";
        }
        @Override
        public int hashCode() {
            return this.id;
        }
        @Override
        public boolean equals(Object obj) {
            if (obj instanceof Student){
                Student  stu = (Student) obj;
                if (stu.id == this.id)
                    return true;
            }
            return false;
        }
    }
    public class HashSetTest {
        public static void main(String[] args) {
            Set<Student> set = new HashSet<Student>();
            Student s1 = new Student(1);
            Student s2 = new Student(1);
            Student s3 = new Student(2);
            set.add(s1);
            set.add(s2);
            set.add(s3);
            for (Student s : set) {
                System.out.println(s);
            }
        }
    }

    正如上例所示,重写了hashCode()equals()方法来区分同意对象后,就不能存放同以对象了。如果注释这两个方法,则所有Student对象视为不同对象,都可以存放。

    3.2 TreeSet介绍及简单使用

    介绍:

     TreeSet也不能存放重复对象,但是TreeSet会自动排序,如果存放的对象不能排序则会报错,所以存放的对象必须指定排序规则。排序规则包括自然排序和客户排序。

      自然排序:TreeSet要添加哪个对象就在哪个对象类上面实现java.lang.Comparable接口,并且重写comparaTo()方法,返回0则表示是同一个对象,否则为不同对象。

          ②客户排序:建立一个第三方类并实现java.util.Comparator接口。并重写方法。定义集合形式为TreeSet ts = new TreeSet(new 第三方类());

    实例

    下面一个例子用TreeSet存放自然排序的对象:

    package com.set;
    
    import java.util.Set;
    import java.util.TreeSet;
    
    class Student1 implements Comparable<Student1>{
        int id;
        public Student1(int id) {
            this.id = id;
        }
        @Override
        public String toString() {
            return this.id+"";
        }
        @Override
        public int hashCode() {
            return this.id;
        }
        @Override
        public boolean equals(Object obj) {
            if (obj instanceof Student1){
                Student1  stu = (Student1) obj;
                if (stu.id == this.id)
                    return true;
            }
            return false;
        }
        public int compareTo(Student1 o) {
            return (this.id-o.id);
        }
    }
    
    public class TreeSetTest {
        public static void main(String[] args) {
            Set<Student1> set = new TreeSet<Student1>();
            Student1 s1 = new Student1(5);
            Student1 s2 = new Student1(1);
            Student1 s3 = new Student1(2);
            Student1 s4 = new Student1(4);
            Student1 s5 = new Student1(3);
            set.add(s1);
            set.add(s2);
            set.add(s3);
            set.add(s4);
            set.add(s5);
            for (Student1 s : set) {
                System.out.println(s);
            }
        }
    
    }

     输出结果为:

    1
    2
    3
    4
    5

    3.3 Linked HashSet介绍

    介绍:LinkedHashSet按照插入顺序保存对象,同时还保存了HashSet的查询速度。

     


    4  Map介绍及简单使用

    介绍:

    Map接口中键和值一一映射. 可以通过键来获取值。

    给定一个键和一个值,你可以将该值存储在一个Map对象. 之后,你可以通过键来访问对应的值。

    当访问的值不存在的时候,方法就会抛出一个NoSuchElementException异常.

    当对象的类型和Map里元素类型不兼容的时候,就会抛出一个 ClassCastException异常。

    当在不允许使用Null对象的Map中使用Null对象,会抛出一个NullPointerException 异常。 

    当尝试修改一个只读的Map时,会抛出一个UnsupportedOperationException异常。

    序号

    方法描述

    1

    void clear( )
     从此映射中移除所有映射关系(可选操作)。

    2

    boolean containsKey(Object k)
    如果此映射包含指定键的映射关系,则返回 true。

    3

    boolean containsValue(Object v)
    如果此映射将一个或多个键映射到指定值,则返回 true。

    4

    Set entrySet( )
    返回此映射中包含的映射关系的 Set 视图。

    5

    boolean equals(Object obj)
    比较指定的对象与此映射是否相等。

    6

    Object get(Object k)
    返回指定键所映射的值;如果此映射不包含该键的映射关系,则返回 null。

    7

    int hashCode( )
    返回此映射的哈希码值。

    8

    boolean isEmpty( )
    如果此映射未包含键-值映射关系,则返回 true。

    9

    Set keySet( )
    返回此映射中包含的键的 Set 视图。

    10

    Object put(Object k, Object v)
    将指定的值与此映射中的指定键关联(可选操作)。

    11

    void putAll(Map m)
    从指定映射中将所有映射关系复制到此映射中(可选操作)。

    12

    Object remove(Object k)
    如果存在一个键的映射关系,则将其从此映射中移除(可选操作)。

    13

    int size( )
    返回此映射中的键-值映射关系数。

    14

    Collection values( )
    返回此映射中包含的值的 Collection 视图。

     

     实例 

    import java.util.*;
    public class CollectionsDemo {
    
       public static void main(String[] args) {
          Map m1 = new HashMap(); 
          m1.put("Zara", "8");
          m1.put("Mahnaz", "31");
          m1.put("Ayan", "12");
          m1.put("Daisy", "14");
          System.out.println();
          System.out.println(" Map Elements");
          System.out.print("	" + m1);
       }}

    以上实例编译运行结果如下:

    Map Elements
            {Mahnaz=31, Ayan=12, Daisy=14, Zara=8}

    4.1 Hashtable介绍及简单使用

    介绍:

    Hashtable是原始的java.util的一部分, 是一个Dictionary具体的实现 。

    然而,Java 2 重构的Hashtable实现了Map接口,因此,Hashtable现在集成到了集合框架中。它和HashMap类很相似,但是它支持同步。

    HashMap一样,Hashtable在哈希表中存储键/值对。当使用一个哈希表,要指定用作键的对象,以及要链接到该键的值。

    然后,该键经过哈希处理,所得到的散列码被用作存储在该表中值的索引。

    实例

    下面的程序说明这个数据结构支持的几个方法:

    import java.util.*;
    public class HashTableDemo {
    
       public static void main(String args[]) {
          // Create a hash map
          Hashtable balance = new Hashtable();
          Enumeration names;
          String str;
          double bal;
    
          balance.put("Zara", new Double(3434.34));
          balance.put("Mahnaz", new Double(123.22));
          balance.put("Ayan", new Double(1378.00));
          balance.put("Daisy", new Double(99.22));
          balance.put("Qadir", new Double(-19.08));
    
          // Show all balances in hash table.
          names = balance.keys();
          while(names.hasMoreElements()) {
             str = (String) names.nextElement();
             System.out.println(str + ": " +
             balance.get(str));
          }
          System.out.println();
          // Deposit 1,000 into Zara's account
          bal = ((Double)balance.get("Zara")).doubleValue();
          balance.put("Zara", new Double(bal+1000));
          System.out.println("Zara's new balance: " +
          balance.get("Zara"));
       }}

    以上实例编译运行结果如下:

    Qadir: -19.08Zara: 3434.34Mahnaz: 123.22Daisy: 99.22Ayan: 1378.0
    Zara's new balance: 4434.34

    4.2 HashMap简单使用

    介绍:以下实例演示了如何使用 Collection 类的 iterator() 方法来遍历集合:

    import java.util.*;
    public class Main {
       public static void main(String[] args) {
          HashMap< String, String> hMap = 
          new HashMap< String, String>();
          hMap.put("1", "1st");
          hMap.put("2", "2nd");
          hMap.put("3", "3rd");
          Collection cl = hMap.values();
          Iterator itr = cl.iterator();
          while (itr.hasNext()) {
             System.out.println(itr.next());
         }
       }}

    以上代码运行输出结果为:

    3rd
    2nd
    1st

    4.3 WeakHashMap介绍

    介绍:

      WeakHashMap实现了Map接口,是HashMap的一种实现,他使用弱引用作为内部数据的存储方案,WeakHashMap可以作为简单缓存表的解决方案,当系统内存不够的时候,垃圾收集器会自动的清除没有在其他任何地方被引用的键值对。

       如果需要用一张很大的HashMap作为缓存表,那么可以考虑使用WeakHashMap,当键值不存在的时候添加到表中,存在即取出其值。

    WeakHashMap weakMap = new WeakHashMap<Integer, byte[]>();
    
    for(int i = 0; i < 10000; i++){
    
    Integer ii = new Integer(i);
    
    weakMap.put(ii, new byte[i]);
    
    }

    参考资料:

          1、Java Vector 类

           2、Java 实例 - HashMap遍历

           3、Java Hashtable 接口

           4、Java Map 接口

           5、Java Stack 类

           6、Java集合类详解

           7、java笔记四:Set接口

  • 相关阅读:
    计算机网络精华知识总结01
    使用hexo创建github博客
    Android Toolbar样式定制详解
    我的PhoneGap安装配置经历
    APMServ5.2.6升级PHP
    WordPress网站更换老鹰主机详细操作
    Windows下的SVN环境搭建详解
    最新Android 出现Please ensure that adb is correctly located at问题的解决方法
    QSqlDatabase
    Qt Pro相关
  • 原文地址:https://www.cnblogs.com/liuzhen1995/p/6093962.html
Copyright © 2011-2022 走看看