JavaSE笔记-集合

Java集合大致可分为:List,Set,Map,Queue

List:有序,可重复

Set:无序(输出和插入顺序不一定一致),不可重复

Map:映射关系,根据key去访问value

Queue:队列,先进先出(FIFO)

集合类只能存储对象

List<int>       //错误
List<Integer>

Collection体系结构

圆圈表示:interface

长方形表示:class

带三角的实线代表继承关系,使用关键字extends

带三角的虚线代表实现关系,使用关键字implements

Iterable

iterable定义了iterator(),forEach(Consumer<? super T> action)

这2个方法用于遍历元素

1.forEach方法遍历集合

Consumer是一个函数式接口,只有一个accept(T t)方法,可以使用Lambda表达式

    public static void main(String[] args){
        Collection<String> coll = new HashSet<>();
        //在集合中添加10个元素
        for(int i=0;i<10;i++){
            coll.add("小王"+i);
        }
        //使用forEach遍历集合
        coll.forEach(name->System.out.println(name));
    }

输出(因为HashSet并未实现SortedSet接口,所以里边的元素是无序的)

2.iterator()遍历集合

集合类使用iterator()方法,会返回一个Iterator

Iterator接口主要用于遍历Collection中的元素

有上边的4个方法,其中forEachRemaining()用来使用Lambda表达式来遍历集合

  2.1不使用Lambda表达式

    public static void main(String[] args){
        Collection<String> coll = new ArrayList<>();
        //在集合中添加10个元素
        for(int i=0;i<10;i++){
            coll.add("小王"+i);
        }
        //获得一个iterator
        Iterator<String> iterator = coll.iterator();
        //iterator中是否还有下一个元素
        while(iterator.hasNext()){
            //返回集合中的下一个元素
            String name = iterator.next();
            System.out.println(name);
            //删除一个元素
            if("小王5".equals(name)){
                iterator.remove();
            }
            //更改iterator中元素,但是集合中的元素没有改变
            //因此可以得出集合传给iterator的是元素的值,而不是引用
            name = "李四";
        }
        System.out.println(coll.contains("小王5"));
    }

注意在使用iterator迭代集合元素的过程中(不要在while循环里边改coll),不要改变集合中的元素,否则会产生ConcurrentModificationException

  2.2使用Lambda表达式

    public static void main(String[] args){
        Collection<String> coll = new ArrayList<>();
        //在集合中添加10个元素
        for(int i=0;i<10;i++){
            coll.add("小王"+i);
        }
        //获得一个iterator
        Iterator<String> iterator = coll.iterator();
        iterator.forEachRemaining(name->System.out.println(name));
    }

3.使用foreach循环来遍历元素

    public static void main(String[] args){
        Collection<String> coll = new ArrayList<>();
        //在集合中添加10个元素
        for(int i=0;i<10;i++){
            coll.add("小王"+i);
        }

        for(String name:coll){
            System.out.println(name);
        }
}

注意在使用foreach遍历集合元素的过程中(不要在for循环里边改coll),不要改变集合中的元素,否则会产生ConcurrentModificationException

Collection

Collection中的操作可以操作所有的List,Set,Queue

   public static void main(String[] args){
        Collection<String> coll = new ArrayList<>();
        //在集合中添加一个元素
        coll.add("张三");
        //返回true
        System.out.println(coll.contains("张三"));
        //返回1
        System.out.println(coll.size());
        //删除元素
        coll.remove("张三");
        //返回0
        System.out.println(coll.size());
        //在集合中添加10个元素
        for(int i=0;i<10;i++){
            coll.add("小王"+i);
        }
        //把集合转换成数组
        String[] array = coll.toArray(new String[10]);
        System.out.println(array[5]);
    }

 Set

特点是不允许包含重复元素,继承自Collection接口,没有添加额外方法

1.HashSet

特点

不保证有序

线程不安全,有2个线程同时修改HashSet时,需要通过代码同步

集合元素可以是null

数据结构:散列表
HashSet判定2个元素相等的条件是:1.equals()方法比较相等  2.hashCode()返回值相等

class A{
    @Override
    public boolean equals(Object obj) {
        return true;
    }
}

class B{
    @Override
    public int hashCode() {
        return 1;
    }

    @Override
    public boolean equals(Object obj) {
        return true;
    }
}

class C{
    @Override
    public int hashCode() {
        return 2;
    }
}
public class Test {
    public static void main(String[] args){
        Set<Object> set = new HashSet<>();
        //仅equals()相同
        set.add(new A());
        set.add(new A());
        //hashCode(),equals()均相同
        set.add(new B());
        set.add(new B());
        //仅hashCode()相同
        set.add(new C());
        set.add(new C());
        for(Object a : set){
            System.out.println(a);
        }
    }

输出

可以看出只有B,equals和hashCode都相同时,HashSet才会认为这2个元素使同一个元素

当hashCode相同时,HashSet会把多个元素放在一个bucket中,构成同义词链表,会减慢访问速度

因此,使用HashSet时,要保证2个对象equals返回true时,hashCode也要返回true

2.TreeSet

特点

排过序

线程不安全,有2个线程同时修改HashSet时,需要通过代码同步

数据结构:红黑树

TreeSet的排序规则

  2.1自然排序 (默认)

调用集合元素的compareTo(Object obj)方法比较元素大小关系,然后按元素大小升序排列

a.compareTo(b)

a>b,返回正数

a=b,返回0

a<b,返回负数

使用TreeSet时,要保证2个对象equals返回true时,a.compareTo(b)要返回0

因此在向TreeSet中添加元素时,要实现Comparable接口,否则抛出ClassCashException

    public static void main(String[] args){     //Integer已经实现Comparable接口
        TreeSet<Integer> set = new TreeSet<>();
        set.add(5);
        set.add(4);
        set.add(9);
        set.add(2);
        for(Integer i : set){
            System.out.println(i);
        }
    }

输出

  2.2通过Comparator接口(函数式接口)

  

compare(a,b)

返回正数,a>b

返回0,a=b

返回负数,a<b

实现逆序,返回相反的数就行了

    public static void main(String[] args) {     //使用TreeSet(Comparator<? super E> comparator)构造
        TreeSet<Integer> set = new TreeSet<>(
                (num1,num2)-> {
                    if (num1 < num2)
                        return 1;
                    if(num1 > num2)
                        return -1;
                    return 0;
                }
        );
        set.add(9);
        set.add(1);
        set.add(3);
        for (int num : set){
            System.out.println(num);
        }
    }

输出

3.EnumSet

  所有元素必须是enum类型

  EnumSet是有序的

  不允许放入null

  没有构造器, 通过静态方法获得EnumSet

List

特点是元素有序,可重复,继承自Collection接口,还添加了一些根据索引操作元素的方法

  List判断2个元素相等的条件是equals方法返回true

set方法只能用于修改集合中已经存在的值,不能新增加元素。

使用List的sort方法进行排序

    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.add("张三");
        list.add("李小四");
        list.add("王大少爷");
        //集合的顺序是张三,李小四,王大少爷
        list.sort(
                ((o1, o2) ->{
                    if(o1.length() < o2.length())
                        return 1;
                    if(o1.length() == o2.length())
                        return 0;
                    return -1;
                } )
        );
        for (String s: list) {
            System.out.println(s);
        }
    }

输出

 使用ListIterator迭代

ListIterator()方法返回一个ListIterator,ListIterator增加了向前迭代元素的方法,以及添加元素的方法

   public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.add("张三");
        list.add("李小四");
        list.add("王大少爷");
        //集合的顺序是张三,李小四,王大少爷
        ListIterator<String> listIterator = list.listIterator();
        //注意这里调用add方法采用的是头插法
        listIterator.add("周杰伦");
        System.out.println(list);
        while(listIterator.hasNext()){
            listIterator.next();
        }
        System.out.println("你还想怎么样啊,到底了");
        System.out.println("========================");
        System.out.println("我还能反着遍历元素啊");
        while(listIterator.hasPrevious()){
            System.out.println(listIterator.previous());
        }
    }

输出

 ArrayList,Vector

ArrayList,Vector是List的2个典型实现,调用不带参数构造方法,initialCapacity=10;带参数的构造方法,自己指定initialCapacity

ArrayList不是线程安全的,Vector是线程安全的

Queue

数据结构:队列(FIFO)

不允许随机访问

element()方法返回头元素,不删除集合中元素

peek()方法返回头元素或者null,不删除集合中元素

poll()方法返回头元素或者null,删除集合中元素

1.PriorityQueue

  按元素大小重新排序,因此取出头元素时,是最小的元素

  PriorityQueue不允许插入null

  PriorityQueue对元素的排序方法同样有2种,自然排序和定制排序,思路和TreeSet一样

2.Deque和ArrayDeque

  Deque代表一个双端队列

它们功能相同,区别是对失败情况的处理不同。一套接口遇到失败就会抛出异常,另一套遇到失败会返回特殊值(falsenull

  ArrayDeque底层也是数组,数组长度默认是16

ArrayDeque可以作为栈和队列使用(推荐)

作为栈时使用下面2个方法操作元素

作为队列时使用下面方法操作元素

LinkedList

  实现了List和Deque 2个接口,底层是链表,随机访问效率较差,插入删除效率高

  LinkedList采用迭代器方式遍历效率高,ArrayList,Vector使用get效率高

Map体系结构

 Map

  Key:无序,不可重复->组成一个keySet

  Value:有序,可重复->组成一个List

   public static void main(String[] args){
        Map<Integer,String> map = new HashMap<Integer,String>();
        //添加元素
        map.put(1,"张三");
        map.put(2,"李四");
        map.put(3,"王五");
        //key是唯一的,如果放入相同的key,会把现有的覆盖
        map.put(3,"赵子龙");
        //输出赵子龙
        System.out.println(map.get(3));
        //删除赵子龙
        map.remove(3);
        //遍历
        for (int i : map.keySet()){
            System.out.println(map.get(i));
        }

    }

HashMap,Hashtable

  区别:1.HashMap线程不安全,Hashtable线程安全

     2.HashMap可以使用null作为key和value(由于key是不可重复的,因此key只能有1个可以为null,value可以有无数个),Hashtable不可以

  判定key和value是否相等

  判定key相等通过equals()方法和hashCode()方法,判定value相等通过equals()方法

 

class MyKey{
    private int key;

    public MyKey(int key){
        this.key = key;
    }
    @Override
    public boolean equals(Object obj) {
        MyKey k = (MyKey) obj;
        if(key == k.key)
        return true;
        return false;
    }

    @Override
    public int hashCode() {
        return key;
    }
}
public class Test {
    public static void main(String[] args){
        Map<MyKey,String> map = new HashMap<>();
        map.put(new MyKey(1),"张三");
        map.put(new MyKey(2),"李四");
        //key相同,会覆盖原来的
        map.put(new MyKey(1),"周杰伦");
        //输出{[email protected]=周杰伦, [email protected]=李四}
        System.out.println(map);
        //返回true
        System.out.println(map.containsValue("李四"));
    }
}

LinkedHashMap

  LinkedHashMap使用双向链表维护key,确保key插入顺序与迭代顺序一致

Properties

  Properties相当于一个key,value都是String的Map

  使用Properties读取配置文件

    public static void main(String[] args){
        Properties properties = new Properties();
        try {
            properties.load(new InputStreamReader(new FileInputStream("properties"),"utf-8"));
            System.out.println(properties);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

 TreeMap

  数据结构:红黑树

  每个key-value对作为红黑树节点

  2种排序方式:自然排序和定制排序(看key,与TreeSet判等规则一致)

WeakHashMap

  与HashMap区别:WeakHashMap的key中保存的是弱引用,HashMap中保存的是强引用

  如果WeakHashMap中的key没有被其他强引用变量引用,这些key有可能被GC回收

IdentityHashMap

  与HashMap区别:IdentityHashMap只有当key1 == key2 才认为2个key相等,HashMap两个key的equals,hashCode相等即相等

工具类Collections

 对List的操作

 public static void main(String[] args){
        List<Integer> list = new ArrayList<>();
        for (int i=0; i<10;i++){
            list.add(i);
        }
        //输出[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
        System.out.println(list);
        //逆序
        Collections.reverse(list);
        //输出[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
        System.out.println(list);
        //随机排序
        Collections.shuffle(list);
        System.out.println(list);
        //升序排序
        Collections.sort(list);
        System.out.println(list);
        //二分查找指定元素位置,List必须有序
        System.out.println(Collections.binarySearch(list,5));
    }

  查找Collection最大最小值

    public static void main(String[] args){
        Collection<Integer> c = new HashSet<>();
        for (int i=0;i<10;i++){
            c.add(i);
        }
        //最大值9
        System.out.println(Collections.max(c));
        //最小值0
        System.out.println(Collections.min(c));
    }

  同步集合

  

通过上面3个方法得到同步后的集合,确保线程安全

原文地址:https://www.cnblogs.com/vshen999/p/8365947.html

时间: 2024-10-12 12:09:10

JavaSE笔记-集合的相关文章

【史上最强JavaSE笔记】之数组篇

各位程序猿,各位攻城狮,各位蜥蜴鸥以及各位棕鲸鲤们~~大家好,我是潘师傅,欢迎大家收看由我为你们带来的[史上最强JavaSE笔记]系列,其实也可以叫[嘻哈JavaSE笔记]的,第一次在博客园发帖,想想还真是有点小激动呢,各位求支持呀,哈哈,那么回归正题,我把自己之前学习积累的笔记拿出来跟大家分享一下,方便大家更好的理解和复习,希望能够对大家有所帮助哈,这次发的是JavaSE方面数组篇的,内容不一定全面哦,欢迎大家前来留言交流哈,不足的地方还望大家多多指出和指导哈~(由于首次发文章,布局可能比较乱

C语言、数据结构笔记集合

链表中的“p->next” p->next到底是指p的下一个节点还是p的指针域呢?p是一个指针,那么p->next也应该是一个指针,即p->next应该是一个地址,因此p->next其实是p指向的节点的指针域(next域),所以p->next还是属于当前节点的,只不过它是下一个节点的地址罢了.所以如果函数返回“p->next”,那么函数的类型应为指针函数. 如何让VS2013进行C编程的时候使用基本库函数不会得到警告 把VS项目创建中的安全周期检查关闭就可以任意使

&lt;代码整洁之道&gt;、&lt;java与模式&gt;、&lt;head first设计模式&gt;读书笔记集合

一.前言                                                                                       几个月前的看书笔记,内容全部都是摘自书中比较精辟的句子.笔记都是一段一段的句子,故没有文章的篇幅概念,仅供温习之用,更多详细内容请看原书!!! <代码整洁之道>里面有很多前人编写简洁.漂亮代码的经验.当然书中作者的经验并不100%适合每个人,但大部分都是可借鉴的! <java与模式>这本书内容太多了,我

JAVASE笔记回顾

第一部分,JAVA基础和面向对象 part01 入门与开发环境搭建 1: 计算机基础知识(了解)(1)计算机(2)计算机硬件(3)计算机软件系统软件:windows,linux,mac应用软件:QQ,YY,扫雷,CS/F(4)软件开发就是用开发工具和计算机语言做出软件(5)计算机语言人与计算机的交流方式(6)人机交互A:图像界面方便,简单,直观.B:DOS 窗口方式要有控制台, 要记住很多的命令, 麻烦.(7)键盘功能键和快捷键的介绍(掌握)A:键盘功能键tabshiftctrlalt空格ent

JavaSE——链表集合

声明:本栏目所使用的素材都是凯哥学堂VIP学员所写,学员有权匿名,对文章有最终解释权:凯哥学堂旨在促进VIP学员互相学习的基础上公开笔记. 链表集合: 优点:1.有序2.可以向前面和向后添加3.中间插入也很方便4.可以使用它实现简单队列模式 缺点:1.消耗内存有点大2.定位删除和定位查找都是比较满的 如下图:指定对象删除方法,按指定对象移除,就是找到你要找的那个对象然后移除,如下图这遍代码就是帮你找,如果没有找着,那就帮你找下家,如果还不对,又循环又帮你找下家,直到找到null为止 上面已经做好

java课堂笔记------集合api

Collection c = new ArrayList(); * boolean add(E e) * 将当前集合中添加给定的元素 * 若成功添加则返回true c.add("one"); c.add("two"); * int size() * 获取当前集合中的元素个数 c.size(); * boolean isEmpty() * 判断当前集合是否不包含任何元素 * 当集合中没有元素时返回true boolean isEmpty = c.isEmpty();

笔记--集合

单例集合 ----------| Collection 单例集合 的根接口----------------| List 如果是实现了List接口的集合类,具备的特点: 有序,可重复.-------------------| ArrayList ArrayList底层是使用了Object数组实现 的. 特点: 查询速度快,增删慢.-------------------| LinkedList LinkedList底层是使用了链表数据结构实现的.特点: 查询速度慢,增删快--------------

python笔记--集合

集合set set和dict类似,也是一组key的集合,但不存储value.所以,特点是无序.不重复.基本功能包括消除重复元素和关系测试. 集合对象还支持并.交.差.对称差数学运算. 一.定义集合 >>> s=set([1,2,3]) >>> s set([1, 2, 3]) 要创建一个set,需要提供一个list作为输入集合, 注意:传入的参数[1, 2, 3]是一个list,而显示的set([1, 2, 3])只是告诉你这个set内部有1,2,3这3个元素,显示的[

javase(Properties集合及学生对象信息录入文本中案例)

1.Properties集合 Properties和IO流的结合使用 1 public void load(Reader reader) 2 public void store(Writer writer,String comments) 3 /* 4 * 这里的集合必须是Properties集合: 5 * public void load(Reader reader):把文件中的数据读取到集合中 6 * public void store(Writer writer,String commen