Java集合(集合框架)

Java集合(集合框架)

 

Java标准库自带的java.util包提供了集合类。Java集合就像一种容器,可以含有多个对象(实际上是对象的引用,但习惯上都称对象),从Java 5 增加了泛型以后,Java集合可以记住容器中对象的数据类型,使得编码更加简洁、健壮。

Java集合大致可以分为两大体系,一个是Collection,另一个是Map。

Collection :主要由List、Set、Queue接口组成,List代表有序、重复的集合;其中Set代表无序、不可重复的集合;Java 5 又增加了Queue体系集合,代表一种队列集合实现。

Map:则代表具有映射关系的键值对集合。

【Java的集合设计非常久远,中间经历过大规模改进,有些不应该继续使用:向量(Vector)、哈希表(Hashtable)、堆栈(Stack)。】

 

先介绍Collection,再介绍Map。

 

Collection

Java集合是一个对象,可容纳其他对象的引用。集合接口声明对每一种类型的集合可以执行的操作。Java集合框架为程序员提供了预先包装的数据结构和算法来操纵他们。

java.util.Collection下的接口和继承类关系简易结构图如下:

 

 

集合框架包含如下内容:

☆接口:是代表集合的抽象数据类型。例如 Collection、List、Set等。之所以定义多个接口,是为了以不同的方式操作集合对象。如:

Collection 接口是Collection层次结构的根接口。List 接口继承于Collection和一个 List实例存储一个有序集合的元素。Set接口继承于 Collection,是一个不包含重复元素的集合。SortedSet接口继承于

☆实现(类):是集合接口的具体实现。从本质上讲,它们是可重复使用的数据结构,例如:ArrayList类实现动态数组。LinkedList实现链表。TreeSet类使用元素的自然顺序对元素进行排序。

☆算法:是实现集合接口的对象里的方法执行的一些有用的计算,例如:搜索和排序。这些算法被称为多态,那是因为相同的方法可以在相似的接口上有着不同的实现。

 

List接口

List是最基础的一种集合:它是一种有序列表。

List的行为和数组几乎完全相同:List内部按照放入元素的先后顺序存放,每个元素都可以通过索引确定自己的位置,List的索引和数组一样,从0开始。但是,使用数组,在添加和删除元素的时候,会非常不方便,因此,在实际应用中,需要增删元素的有序列表,我们使用最多的是ArrayList。ArrayList把添加和删除的操作封装起来,让我们操作List类似于操作数组,却不用关心内部元素如何移动。

另一种LinkedList通过“链表”也实现了List接口。在LinkedList中,它的内部每个元素都指向下一个元素:

ArrayList类和LinkedList类的比较:

 

 

ArrayList

LinkedList

获取指定元素

速度很快

需要从头开始查找元素

添加元素到末尾

速度很快

速度很快

在指定位置添加/删除

需要移动元素

不需要移动元素

内存占用

较大

 

ArrayList类的构造方法有:

1、无参的构造函数: ArrayList()构造一个初始容量为10的空列表。

2、一个int类型的构造函数: ArrayList(int initialCapacity)构造一个具有指定初始容量initialCapacity的空列表。

3、一个指定collection的构造函数: ArrayList(Collection<? extends E> c)构造一个包含指定collection的元素的列表,这些元素是按照该collection的迭代器返回它们的顺序排列的。该构造方法主要就是将Collection集合的实现类转换为ArrayList。

 

ArrayList类常用方法

1、add(Object element): 向列表的尾部添加指定的元素。

2、size(): 返回列表中的元素个数。

3、get(int index): 返回列表中指定位置的元素,index从0开始。

4、add(int index, Object element): 在列表的指定位置插入指定元素。

5、 set(int i, Object element): 将索引i位置元素替换为元素element并返回被替换的元素。

6、clear(): 从列表中移除所有元素。

7、isEmpty(): 判断列表是否包含元素,不包含元素则返回 true,否则返回false。

8、contains(Object o): 如果列表包含指定的元素,则返回 true。

9、remove(int index): 移除列表中指定位置的元素,并返回被删元素。

10、remove(Object o): 移除集合中第一次出现的指定元素,移除成功返回true,否则返回false。

11、iterator(): 返回按适当顺序在列表的元素上进行迭代的迭代器。

 

例1、使用ArrayList的例子

import java.util.*;

import java.util.*;

public class ListTest {

    public static void main(String[] args) {

        ArrayList<Integer> myNumbers = new ArrayList<Integer>();

        myNumbers.add(10);

        myNumbers.add(15);

        myNumbers.add(20);

        myNumbers.add(25);

        for (int i : myNumbers) {

            System.out.println(i);

        }

    }

}

运行输出:

10

15

20

25

 

例2、遍历 ArrayList示例

import java.util.*;

public class ListTestA{

 public static void main(String[] args) {

     List<String> list=new ArrayList<String>();

     list.add("Hello");

     list.add("World");

     list.add("HAHAHAHA");

     //第一种遍历方法使用 For-Each 遍历 List

     for (String str : list) {            //也可以改写 for(int i=0;i<list.size();i++) 这种形式

        System.out.println(str);

     }

 

     //第二种遍历,把链表变为数组相关的内容进行遍历

     String[] strArray=new String[list.size()];

     list.toArray(strArray);

     for(int i=0;i<strArray.length;i++) //这里也可以改写为  for(String str:strArray) 这种形式

     {

        System.out.println(strArray[i]);

     }

    

    //第三种遍历 使用迭代器进行相关遍历

    

     Iterator<String> ite=list.iterator();

     while(ite.hasNext())//判断下一个元素之后有值

     {

         System.out.println(ite.next());

     }

 }

}

三种方法都是用来遍历ArrayList集合,第三种方法是采用迭代器的方法,该方法可以不用担心在遍历的过程中会超出集合的长度。运行输出:

Hello

World

HAHAHAHA

Hello

World

HAHAHAHA

Hello

World

HAHAHAHA

 

 

LinkedList类

链表(Linked list)是一种常见的基础数据结构,是一种线性表,但是并不会按线性的顺序存储数据,而是在每一个节点里存到下一个节点的地址。

链表可分为单向链表和双向链表。

一个单向链表包含两个值: 当前节点的值和一个指向下一个节点的链接。

一个双向链表有三个整数值: 数值、向后的节点链接、向前的节点链接。

 

 

Java LinkedList(链表) 类似于 ArrayList,是一种常用的数据容器。

与 ArrayList 相比,LinkedList 的增加和删除对操作效率更高,而查找和修改的操作效率较低。

以下情况使用 ArrayList :

频繁访问列表中的某一个元素。

只需要在列表末尾进行添加和删除元素操作。

以下情况使用 LinkedList :

你需要通过循环迭代来访问列表中的某些元素。

需要频繁的在列表开头、中间、末尾等位置进行添加和删除元素操作。

 

LinkedList类的构造方法有:

1、默认构造函数

LinkedList()

2、创建一个LinkedList,保护Collection中的全部元素。

LinkedList(Collection<? extends E> c)

 

LinkedList 类的常用方法

1、add( element) 向链表末尾添加一个新节点,该节点中的数据是参数element指定的对象

2、add( index, element) 向链表指定位置添加一个新节点,该节点中的数据是参数element指定的对象

3、addFirist( element) 向链表表头添加一个新节点,该节点中的数据是参数element指定的对象

4、addLast( element) 向链表表尾添加一个新节点,该节点中的数据是参数element指定的对象

5、removeFirst()删除第一个节点并返回这个节点中的对象

6、removeLast() 删除最后一个节点并返回这个节点中的对象

7、remove( index) 删除指定位置的节点

8、get( index) 得到指定位置的节点

9、getFirst() 得到链表第一个节点的对象

10、getLast() 得到链表最后一个节点的对象

11、indexOf( element) 返回节点对象element在链表中首次出现的位置,如果链表中无此节点的对象则返回-1

12、lastIndexOf( element) 返回节点对象element在链表中最后出现的位置,如果链表中无此节点的对象则返回-1

13、set( index, element) 将当前链表index位置节点中的对象替换成参数element指定的对象,返回被替换对象

14、size() 返回链表的长度即节点个数

15、contains( element) 判断链表节点对象中是否含有element

 

例1、使用LinkeList类的例子

import java.util.*;

public class LListTest

{

     public static void main(String[] args)

     {

          //创建列表LinkedList类的对象

          LinkedList ll=new LinkedList();

          //初始化LinkedList对象

          for(int i=0;i<5;i++)

          {

               ll.add(String.valueOf(i));

          }

          //对LinkedList进行插入操作

          for(int i=5;i<10;i++)

          {

               ll.add(i,String.valueOf(10-i+5));

          }

          //打印LinkedList列表

          System.out.println("这里是LinkedList操作后的结果:");

          System.out.println(ll);

     }

}

运行输出:

这里是LinkedList操作后的结果:

[0, 1, 2, 3, 4, 10, 9, 8, 7, 6]

 

例2、使用LinkeList类进行设置、删除元素

import java.util.*;

public class   LListTestA

{

    public static void main(String[] args)

    {

        //创建一个LinkedList对象

        LinkedList<String> liList = new LinkedList<String>();  //参数与返回值都必须为String类型

        for (int i = 0; i < 5; i++)

        {      //循环加入5个字符串对象

            liList.add(String.valueOf(i));

        }

        System.out.println(liList);    //输出liList对象中的元素

        System.out.println(liList.get(3));   //输出liList对象位置3的元素

        liList.set(3, "aaa");        //设置位置3的元素为"555"

        System.out.println(liList);

        System.out.println(liList.peek());       //找到列表的头元素

        System.out.println(liList);

        System.out.println(liList.poll());       //找到列表的头元素并删除

        System.out.println(liList);

        System.out.println("第一个元素是" + liList.getFirst());   //获取第一个元素并输出

        System.out.println("最后一个元素是" + liList.getLast());   //获取最后一个元素并输出

    }

}

 

运行输出:

[0, 1, 2, 3, 4]

3

[0, 1, 2, aaa, 4]

0

[0, 1, 2, aaa, 4]

0

[1, 2, aaa, 4]

第一个元素是1

最后一个元素是4

 

Set接口

Set接口与List接口最大的区别在于Set中没有重复的元素。Set是非常简单的集合,Set中的对象没有特定顺序。Sorted接口具有排序的功能,TreeSet类则是实现了该接口;HashSet类使用哈希算法存取集合中的元素,存取速度比较快。

 

TreeSet

TreeSet是SortedSet接口的实现类,TreeSet可以保证元素处于排序状态,它采用红黑树的数据结构来存储集合元素。TreeSet支持两种排序方法:自然排序和定制排序,默认采用自然排序。

 

TreeSet类的构造方法有:

1、默认构造函数。使用该构造函数,TreeSet中的元素按照自然排序进行排列。

TreeSet()

2、创建的TreeSet包含collection

TreeSet(Collection<? extends E> collection)

3、指定TreeSet的比较器

TreeSet(Comparator<? super E> comparator)

4、创建的TreeSet包含set

TreeSet(SortedSet<E> set)

 

TreeSet类常用方法

1、 add(E e)如果指定的元素尚不存在,则将其添加到此集合中。更正式地说,e如果集合中不包含任何元素,则将指定的元素添加到此集合e2中 Objects.equals(e, e2)。如果此set已包含该元素,则调用将保持set不变并返回false。

2、 addAll(Collection <?extends E > c)将指定集合中的所有元素添加到此集合中。

3、 remove(Object o)如果存在,则从该集合中移除指定的元素。更正式地说,移除元素e,使得 Objects.equals(o, e),如果此set包含这样的元素。返回true此set是否包含该元素(或等效地,如果此set因调用而更改)。(一旦调用返回,该集合将不包含该元素。)

4、 size() 返回此集合中的元素数(其基数)。

5、 isEmpty()true如果此set不包含任何元素,则返回

6、E ceiling​(E e) 返回此set中大于或等于给定元素的最小元素,或者null如果没有这样的元素。

7、E floor(E e) 返回此set中小于或等于给定元素的最大元素,或者null如果没有这样的元素。

8、E lower​(E e) 返回此集合中的最大元素严格小于给定元素,或者null如果没有这样的元素。

9、 contains(Object o)true如果此set包含指定的元素,则返回。更正式地说,返回true当且仅当此set包含的元素e,使得 Objects.equals(o, e)。

 

例1、使用TreeSet类的例子

import java.util.*;

public class TSetTest

{

     public static void main(String[] args)

     {

          //创建了TreeSet对象

          TreeSet ts=new TreeSet();

          //向TreeSet对象中依次添加了数字为5、6、3、2、4的字符串

          ts.add(String.valueOf(5));

          ts.add(String.valueOf(6));

          ts.add(String.valueOf(3));

          ts.add(String.valueOf(2));

          ts.add(String.valueOf(4));

          //移除了HashSet对象中内容为"5"的字符串

          ts.remove(String.valueOf(5));

          //将内容为"1"的字符串添加了进HashSet对象

          ts.add(String.valueOf(1));

          //打印输出TreeSet中的内容

          System.out.print("TreeSet操作后的结果为:");

          System.out.println(ts);

     }

}

运行输出:

TreeSet操作后的结果为:[1, 2, 3, 4, 6]

 

例2、使用TreeSet类的方法的例子

import java.util.*;

public class TSetTestA

{

    public static void main(String[] args) throws Exception

     {

        TreeSet ts = new TreeSet();    //创建一个TreeSet对象

        for (int i = 5; i >= 0; i--)

        {       //循环加入5个整型对象

            ts.add(new Integer(i));

        }

        TreeSet anotherts = (TreeSet) ts.clone();   //复制TreeSet对象

        Iterator it = anotherts.iterator();

        while (it.hasNext())

        {     //循环输出it对象中的元素

            System.out.println(it.next());

        }

        System.out.println("创建TreeSet类");

        TreeSet s = new TreeSet();     //创建一个TreeSet对象

        s.add("aa");      //添加4个字符串元素

        s.add("cc");

        s.add("dd");

        s.add("bb");

        Iterator its = s.iterator();    //为对象s创建一个迭代器对象

        while (its.hasNext())

        {    //遍历输出s中的对象

            System.out.println(its.next());

        }

        System.out.println("第一个元素为:" + s.first());   //输出s对象中的第一个元素

        System.out.println("最后一个元素为:" + s.last());  //输出s对象中的最后一个元素

    }

}

 

运行输出:

0

1

2

3

4

5

创建TreeSet类

aa

bb

cc

dd

第一个元素为:aa

最后一个元素为:dd

 

 

Queue接口

Queue用于模拟队列这种数据结构,队列通常是指“先进先出”(FIFO)的容器。队列的头部是保存在队列中存放时间最长的元素,队列的尾部是保存在队列中存放时间最短的元素。新元素插入(offer)到队列的尾部,访问元素(poll)操作会返回队列头部的元素。

Queue接口有一个PriorityQueue实现类。除此之外,Queue还有一个Deque接口,Deque代表一个“双端队列”,双端队列可以同时从两端来添加、删除元素,因此Deque的实现类既可当成队列使用,也可当成栈使用,Java为Deque提供了实现类ArrayDeque。

 

 

 

Map

java.util包除了集合,该框架也定义了几个 Map 接口和类。Map 里存储的是键/值对。

java.util.Map下的接口和继承类关系简易结构图:

 

 

 

 

附录、

java集合 https://blog.csdn.net/bingxuesiyang/category_8842042.html

Java 集合框架 https://www.runoob.com/java/java-collections.html

 

猜你喜欢

转载自blog.csdn.net/cnds123/article/details/112003418