集合

来源:互联网 发布:执业兽医资格考试软件 编辑:程序博客网 时间:2024/06/10 04:47

集合


集合的概述

Java中集合是一种常用的数据结构,例如:队列、栈、链表等。

集合市一中容器,用于存储数量不等的对象,并按照规范实现一些常用的操作和算法。在使用集合时,不必考虑数据结构和算法的具体实现细节,根据需要直接使用这些集合类并调用相应的方法即可,从而提高了开发效率

Java的集合类主要由两个接口派生而出,分别是Collection和Map派生出的子接口或实现类。

Java的常用集合主要分为三大类:

  1. Set集合:将对象添加到Set集合中,Set集合无法记住添加的顺序,因此Set集合中的元素不能重复,否则就无法识别改元素,访问Set集合中的元素也只能根据元素本身进行访问;

  2. List集合:与数组相似,List集合可以记住每次添加元素的顺序,因此可以根据元素的索引访问List集合中的元素,List集合中的元素可以重复而且长度是可变的;

  3. Map集合:每个元素都是由key/value键值对组成,可以根据每个元素的key来访问对应的value,Map几种的key不允许重复,value可以重复;

Collection接口的类图:

Java集合框架图

迭代器接口(Iterator)

迭代器采用统一的方式对Collection集合中的元素进行遍历操作,开发人员无需关心Collection集合中的类容,直接使用foreach循环遍历集合中的部分或全部元素。

使用Collection集合需要注意的问题:

  • add()、addAll()、remove()、removeAll()和retain()方法可能会引发不支持该操作的UnsupportedOperationException异常;

  • 将一个不兼容的对象添加到集合中时,将产生ClassCastException异常;

  • Collection接口没有提供获取某个元素的方法,但可以通过iterator()方法获取迭代器来遍历集合中的所有元素;

  • 虽然Collection中可以存储任何的Object对象,但不建议同一个集合容器中存储不同类型的对象,建议使用泛型增强集合的安全性,以免引起ClassCastException异常;

集合类

1.List接口

List集合是按照元素的添加顺序来设置元素的索引的,索引从0开始,例如:第一次添加的元素的索引为0,第二次添加的元素的索引为1,第n次添加元素的索引为n-1。当使用无效索引时将产生IndexOutBoundsException异常。

ArrayList和Vector是List接口的两个典型实现类,完全支持List接口中的所有功能方法。ArrayList称为“数组列表”,而Vector称为“向量”,两者都是基于数组实现的列表集合,但该数组是一个动态的、长度可变的、并允许再分配的Object[]数组。

ArrayList类与Vector类:

public class ArrayListTest {    public static void main(String[] args) {        //定义ArrayList集合,并指明集合中存储的数据类型        ArrayList<String> list = new ArrayList<String>();        list.add("Hello");//向list中添加数据        list.add("Word");        list.add("Java");        //如果ArrayList没有指定类型,这样写不报错,但后期对这个数据的取用,则会增加难度        //list.add(15);        System.out.println("-----------foreach--------------");        //使用 foreach 遍历集合        for (String string : list) {            System.out.println(string);        }        System.out.println("-------------i----------------");        list.remove(1); //通过下标移除指定下标的元素        for (int i = 0; i < list.size(); i++) {//直接遍历集合            System.out.println(list.get(i));            }        System.out.println("-------------iterator----------------");        list.remove("Hello");//通过值移除对应的元素        //获取List集合中的Iterator        Iterator<String> iterator = list.iterator();        //判断是否有下一个元素        while (iterator.hasNext()) {            //将下一个元素输出来            System.out.println(iterator.next());        }    }}/** * Vector的用法与ArrayList完全一致, * 只不过Vector加入了线程安全,它里面的方法是同步的, * 这样使Vector效率降低 *  * ArrayList虽然线程不安全,即线程不同步,但效率高  */

Stack类

Stact类是Vector的子类,它具有栈的性质:

public class StackTest {    public static void main(String[] args) {        Stack<String> stack = new Stack<String>();        // 依次向Stack中添加元素        stack.add("Hello");        stack.add("Word");        stack.add("Java");        // 输出Stack中的元素情况,调用Stack中的toString()方法        System.out.println(stack);        while (!stack.empty()) {            // pop()方法是Stack中的元素弹出方法,用于依次取Stack中的元素            System.out.println(stack.pop());        }    }}

2.Set接口

Set集合不能记住元素添加的顺序,因此不能包含相同的元素。

Set接口常用的实现类包括HashSet、TreeSet和EnumSet,这三个实现类各具特色:

  • HashSet是Set接口的典型实现类,大多数使用Set集合时都使用该实现类。HashSet使用Hash算法来存储集合中的元素,具有良好的存、取和查找的特性;

  • TreeSet采用Tree“树”的数据结构来存储集合元素,因此可以保证集合中的元素处于排序状态。TreeSet支持两种排序方式:自然排序和定制排序,默认情况下采用自然排序;

    public class SetTest {    public static void main(String[] args) {        // 定义一个HashSet        HashSet<String> hashSet = new HashSet<String>();        // 向HashSet中添加一组顺序元素        hashSet.add("第1");// 加入了两个相同的元素,另一个元素将不会在集合中        hashSet.add("第1");        hashSet.add("第2");        hashSet.add("第3");        hashSet.add("第4");        /**         * Set集合是无序的,因此Set集合只能用foreach或Iterator遍历         * */        System.out.println("--------hashSet--foreach--------");        for (String string : hashSet) {            System.out.println(string);        }        hashSet.remove("第1");// 移除一个元素        System.out.println("--------hashSet--Iterator--------");        Iterator<String> hash = hashSet.iterator();        while (hash.hasNext()) {            System.out.println(hash.next());        }        System.out.println();        // 定义一个TreeSet        TreeSet<String> treeSet = new TreeSet<String>();        // 向TreeSet中添加一组无序元素        treeSet.add("第1");// 加入了两个相同的元素,另一个元素将不会在集合中        treeSet.add("第1");        treeSet.add("第3");        treeSet.add("第4");        treeSet.add("第2");        /**         * TreeSet集合默认会对元素进行自然排序,         * 当然排过序的集合也是没有下标位置的         * */        System.out.println("--------treeSet--foreach--------");        for (String string : treeSet) {            System.out.println(string);        }        treeSet.remove("第1");// 移除一个元素        System.out.println("--------treeSet--Iterator--------");        Iterator<String> tree = treeSet.iterator();        while (tree.hasNext()) {            System.out.println(tree.next());        }    }}

3.Queue接口

Queue接口(即队列)常用“先进先出”的方式排序各个元素,即最先入队的元素最先出队。它继承Collection接口,除了拥有Collection的基本操作外,它还提供队列的插入、提取和检查操作,且每个操作都存在两种形式:一种操作失败时抛出异常;另一种操作失败时返回一个特殊值(null或false)。

Deque接口(双端队列)是Queue接口的子接口,支持在队列的两端插入和移除元素。

  • 链接列表LinkedList是Deque和List两个接口的实现类,兼具队列和列表两种特性,是最常使用的集合之一。LinkedList不是基于线程安全,如果多个线程同时访问一个LinkedList实例,而其中至少有一个线程从结构上修改列表时,则必须有外部代码手动保持同步。

  • ArrayDeque称为“数组双端队列”,是Deque接口的实现类。 不常用

    1、ArrayDeque没有容量限制,可以根据需要增加容量。

    2、ArrayDeque不是基于线程安全的,不支持多线程的并发访问。

    3、ArrayDeque禁止添加null元素。

    4、ArrayDeque在用作堆栈时,快于Stack;用作队列时,快于LinkedList。

  • PriorityQueue是Queue接口的实现类,是基于优先级的、无界队列,通常称为“优先级队列”。优先级队列的元素按照其自然顺序进行排序,或制定排序,优先级队列不允许使用null元素。依靠自然顺序的优先级队列不允许插入不可比较的对象。不常用

    public class LinkedListTest {    public static void main(String[] args) {        //创建LinkedList的对象        LinkedList<Integer> linkedList = new LinkedList<Integer>();        //给LinkedList集合添加5个元素        for (int i = 0; i < 5; i++) {            linkedList.add(i+1);        }        System.out.println("---------输出5个元素----------");        System.out.println(linkedList);        linkedList.offer(6);//在集合的末尾添加一个元素        linkedList.offerFirst(0);//在集合的开头添加一个元        System.out.println("-------------------------");        System.out.println(linkedList);        System.out.println("\n-------用下标方式遍历集合-------");        for (int i = 0; i < linkedList.size(); i++) {            System.out.print(linkedList.get(i) + ",  ");        }        System.out.println("\n-------查看集合的第一个元素---------");        System.out.println(linkedList.peekFirst());        System.out.println(linkedList);        System.out.println("-------推出集合中的第一个元素----------");        System.out.println(linkedList.pollFirst());        System.out.println(linkedList);        System.out.println("--------弹出集合中的第一个元素---------");        System.out.println(linkedList.pop());        System.out.println(linkedList);    }}

4.Map接口

Map接口是集合框架的另一个根接口,与Collection接口并列。Map是以key/value键值对映射关系存储集合,其key-value键值对映射关系如图:

key-value键值对映射关系图

HashMap和TreeMap是Map体系中两个常用实现类,其特点如下:

  • HashMap是基于哈希算法的Map接口的实现类,该实现类提供所有映射操作,并允许使用null键和null值,但不能保证映射的顺序,即是无序的映射集合;

  • TreeMap是基于“树”结构来存储的Map接口实现类,可以根据其键的自然顺序进行排序,或定制排序方式。

    public class MapTest {    public static void main(String[] args) {        //定义一个HashMap        HashMap<String,String> hashMap = new HashMap<String, String>();        hashMap.put("a", "张三");//向HashMap集合中添加元素        hashMap.put("b", "李四");        hashMap.put("c", "王五");        hashMap.put(null, "not");//可以添加键或者值为空的元素        hashMap.remove("a");//将键为“a”的元素移除        //通过其键 获取值,        System.out.println(hashMap.get("a"));//键为“a”的元素被移除,输出的值为null        System.out.println(hashMap.get("b"));        System.out.println(hashMap.get("c"));        System.out.println(hashMap.get(null));        //定义一个TreeMap        TreeMap<String, String> treeMap = new TreeMap<String, String>();        treeMap.put("1", "zhangsan");//与HashMap一样,添加元素        treeMap.put("2", "lisi");        //treeMap.put(null,null);//不允许添加空值,这样写会报错        //通过其键获取值,不允许用null去获取        System.out.println(treeMap.get("1"));       }}

3.集合转换

在Java中,集合有两大类,分别是Collection接口下List、Set、Queue等集合和Map接口下的HashMap、TreeMap等。将Map集合转换成Collection集合,例如:

public class MapToCollection {    public static void main(String[] args) {        // 定义一个HashMap        HashMap<String, String> hashMap = new HashMap<String, String>();        hashMap.put("a", "张三");// 向HashMap集合中添加元素        hashMap.put("b", "李四");        hashMap.put("c", "王五");        //将Map对象转换成Collection对象        //Set是Collection的子类,        //通过HashMap中的entry()方法可以将Hash对象转换成Set对象        Set<Entry<String,String>> entrySet = hashMap.entrySet();        //用foreach 将Set集合中的Entry输出        for (Entry entry : entrySet) {            System.out.println(entry.getKey() + " : " + entry.getValue());        }        //将HashMap的键通过keySet()方法转换成Set对象,依次输出        Set<String> keySet = hashMap.keySet();        for (String string : keySet) {            System.out.println(string);        }        //将HashMap的值通过values()方法转换成Collection对象,依次输出        Collection<String> values = hashMap.values();        for (String string : values) {            System.out.println(values);        }    }}

4.集合工具类

Java集合框架中还提供了两个非常实用的辅助工具类:Collections和Arrays。用法如下:

Collections工具类

提供了一些对Collection集合常用的静态方法,如:排序、复制、查找、以及填充等操作。

使用Collections工具类为集合进行排序时,集合中的元素必须是Comparable可比较的。即实现Comparable接口和Comparable接口中的compareTo()方法

//实现Comparable接口public class Fruit implements Comparable<Fruit>{    protected String name;    protected float price;    public Fruit(String name, float price) {        this.name = name;        this.price = price;    }    @Override    public String toString() {        return "Fruit [name=" + name + ", price=" + price + "$]";    }    //实现Comparable接口中的compareTo()方法    @Override    public int compareTo(Fruit fruit) {        if (this.price < fruit.price) {            return -1;        } else if (this.price == fruit.price) {            return 0;        } else {            return 1;        }    }}public class Test {    public static void main(String[] args) {        List<Fruit> list = new ArrayList<Fruit>();          list.add(new Fruit("Apple", 2.5f));        list.add(new Fruit("Banana", 3.5f));        list.add(new Fruit("Grape", 2.0f));        list.add(new Fruit("Orange", 1.5f));        System.out.println("---------排序前------------");        for (Fruit fruit : list) {            System.out.println(fruit);        }        /**         * 通过Collections辅助类对集合进行排序         * 排序的集合中的类需实现Comparable接口         * 重写compareTo()方法,按照什么方式排序         * */        Collections.sort(list);        System.out.println("---------排序后------------");        for (Fruit fruit : list) {            System.out.println(fruit);        }        System.out.println("---取排序后集合中的最大、最小值---");        System.out.println(Collections.max(list));        System.out.println(Collections.min(list));    }}

Arrays工具类

Arrays工具类提供了针对数组的各种静态方法,如:排序、复制、查找等操作。

public class Test {    public static void main(String[] args) {        //创建一个Fruit数组        Fruit[] fruits = new Fruit[4];        //实例化        fruits[0] = new Fruit("Apple", 2.5f);        fruits[1] = new Fruit("Banana", 3.5f);        fruits[2] = new Fruit("Grape", 2.0f);        fruits[3] = new Fruit("Orange", 1.5f);        System.out.println("---------排序前------------");        for (Fruit fruit : fruits) {            System.out.println(fruit);        }        //使用Arrays工具类进行排序,Fruit类也要实现Comparable接口才能进行排序        Arrays.sort(fruits);        System.out.println("---------排序后------------");        for (Fruit fruit : fruits) {            System.out.println(fruit);        }        System.out.println("----将Fruit数组转换成字符串-----");        System.out.println(Arrays.toString(fruits));        System.out.println("----将Fruit数组拷贝到一个新数组中-----");        Fruit[] otherFruits = Arrays.copyOfRange(fruits, 3, 4);        for (Fruit fruit : otherFruits) {            System.out.println(fruit);        }    }}
原创粉丝点击