【java基础】集合

集合

集合类位于java.util 包下,集合类又被称为容器

与数组的区别

  • 数组的长度是固定的,集合的长度是可变的
  • 数组可以用来存放基本数据类型,集合存放引用类型,不能存放基本数据类型

如何选择

在这里插入图片描述
collection
在这里插入图片描述
map
在这里插入图片描述

黄色的是接口,蓝色的是实现类

接口名称作 用
Iterator 接口集合的输出接口,主要用于遍历输出(即迭代访问)Collection 集合中的元素,Iterator 对象被称之为迭代器。迭代器接口是集合接口的父接口,实现类实现 Collection 时就必须实现 Iterator 接口。
Collection 接口是 List、Set 和 Queue 的父接口,是存放一组单值的最大接口。所谓的单值是指集合中的每个元素都是一个对象。一般很少直接使用此接口直接操作。
Queue 接口Queue 是 Java 提供的队列实现,有点类似于 List。
Dueue 接口是 Queue 的一个子接口,为双向队列。
List 接口是最常用的接口。是有序集合,允许有相同的元素。使用 List 能够精确地控制每个元素插入的位置,用户能够使用索引(元素在 List 中的位置,类似于数组下标)来访问 List 中的元素,与数组类似。
Set 接口不能包含重复的元素。
Map 接口是存放一对值的最大接口,即接口中的每个元素都是一对,以 key➡value 的形式保存。

Collection

在这里插入图片描述
Set接口和List接口都继承了Collection接口
它们共同的方法有

方法名称说明
boolean add(E e)向集合中添加一个元素,如果集合对象被添加操作改变了,则返回 true。E 是元素的数据类型
boolean addAll(Collection c)向集合中添加集合 c 中的所有元素,如果集合对象被添加操作改变了,则返回 true。
void clear()清除集合中的所有元素,将集合长度变为 0。
boolean contains(Object o)判断集合中是否存在指定元素
boolean containsAll(Collection c)判断集合中是否包含集合 c 中的所有元素
boolean isEmpty()判断集合是否为空
Iterator iterator()返回一个 Iterator 对象,用于遍历集合中的元素
boolean remove(Object o)从集合中删除一个指定元素,当集合中包含了一个或多个元素 o 时,该方法只删除第一个符合条件的元素,该方法将返回 true。
boolean removeAll(Collection c)从集合中删除所有在集合 c 中出现的元素(相当于把调用该方法的集合减去集合 c)。如果该操作改变了调用该方法的集合,则该方法返回 true。
boolean retainAll(Collection c)从集合中删除集合 c 里不包含的元素(相当于把调用该方法的集合变成该集合和集合 c 的交集),如果该操作改变了调用该方法的集合,则该方法返回 true。
int size()返回集合中元素的个数
Object[] toArray()把集合转换为一个数组,所有的集合元素变成对应的数组元素。

在这里插入图片描述

package com.collection;

import java.util.ArrayList;

//import java.util.Map;

//import java.util.Collection;

public class Collection_ {

    public static void main(String[] args) {

        ArrayList arrayList = new ArrayList();

        //添加元素,add(Object )

        arrayList.add("huhu");

        arrayList.add(10);//add(new Integer(10))

        arrayList.add(true);

        System.out.println(arrayList);//[huhu, 10, true]

        //删除元素,remove()

//        arrayList.remove("huhu");

//        System.out.println(arrayList);//[10, true]

//        arrayList.remove(1);//可以传入索引值

//        System.out.println(arrayList);//[10]

        //查找元素是否存在,包含

        boolean b=arrayList.contains("huhu");

        System.out.println(b);//true

        //元素的个数

        System.out.println(arrayList.size());//3

        //判断集合是否为空

        System.out.println(arrayList.isEmpty());//False

        //清空

        arrayList.clear();

        System.out.println(arrayList);//[]

        //添加多个元素

        ArrayList list2=new ArrayList();

        list2.add("haha");

        list2.add("jiji");

        arrayList.addAll(list2);

        System.out.println(arrayList);

        //

    }

}

List

有序的,添加顺序和取出顺序一致,可以重复
在这里插入图片描述

后面是否有向上箭头Collection,代表是否继承自Collection接口

ArrayList
  • get(index),索引是从0开始
  • 可以加入null ,并且可以加入多个 arraylist.add(null);
  • 底层是Object的数组
    • 使用无参构造器创建的对象的大小是10;使用指定大小的构造器,则初始化为指定大小
    • 如需扩容,扩容为原来的1.5倍
    • 参考视频:https://www.bilibili.com/video/BV1fh411y7R8?p=511&spm_id_from=pageDriver&vd_source=1fe29350b37642fa583f709b9ae44b35

    • 适合改查
  • 基本等同于Vector,但是线程不安全;在多线程的情况下不建议使用
Vector

底层也是一个数组,线程同步即线程安全
在这里插入图片描述

LinkedList
  • 底层实现了双向链表和双向队列的特点
  • 可以重复,包括null
  • 线程不安全,没有实现同步
  • 通常不会使用
    在这里插入图片描述

Set

在这里插入图片描述

  • HashSet无序,存储顺序和查询顺序是不一致的(但是取出的顺序是固定的,只有一种)
  • 没有索引,遍历方式没有索引
  • 不能重复
  • 最多只能有一个null

HashSet

import java.util.HashSet;

import java.util.Set;

public class Set_ {

    @SuppressWarnings({"all"})

    public static void main(String[] args) {

        Set set= new HashSet();

        System.out.println(set.add("jiji"));//true

        System.out.println(set.add("haha"));//true

        System.out.println(set.add("huhu"));//true

        System.out.println(set.add("jiji"));//false

        set.remove("jiji");

        System.out.println(set);//[haha, huhu]

        set =new HashSet();

        System.out.println(set.add(new Dog("tom")));//true

        System.out.println(set.add(new Dog("tom")));//true

        System.out.println(set);//[Dog{name='tom'}, Dog{name='tom'}]

        set =new HashSet();

        System.out.println(set.add(new String("haha")));//true

        System.out.println(set.add(new String("haha")));//false

        System.out.println(set);//[haha]

    }

}

class  Dog{

    private String name;

    public Dog(String name) {

        this.name = name;

    }

    @Override

    public String toString() {

        return "Dog{" +

                "name='" + name + '\'' +

                '}';

    }

}

Hashset的底层就是HahMap
数组+链表+红黑树
在这里插入图片描述
扩容

当链表到达8之后,但是table表没到64之前,会把数据继续加到链表后面,同时进行table数组扩容

在这里插入图片描述

LinkedHashSet

  • LinkedHashSet是HashSet的子类
  • Linkedhashset底层是个 Linkedhashmap,底层维护了一个数组+双向链表
  • Linkedhashset根据元素的 hashcode值来决定元素的存储位置,同时使用链表维护元素的次序,这使得元素看起来是以插入顺序保存的
  • Linkedhashset不允许添重复元素

TreeSet

TreeSet底层是TreeMap

想让TreeSet排序,在创建TreeSet的时候传给它一个Comapretor
不传,就采用默认排序,但是存储的内容要可比较,即同一类型

当传入的两个key经过比较相同时,key不会变,value会变

TreeSet<Object> set = new TreeSet<>();
        set.add("bb");
//        set.add(1);//报错
        set.add("aa");
        set.add("cc");
        for (Object o : set) {
            System.out.println(o);
        }
        TreeSet set2 = new TreeSet<>(
                new Comparator() {
                    @Override
                    public int compare(Object o1,Object o2){
                        return ((String)o2).compareTo((String) o1);
                    }
                }
        );
        set2.add("bb");
        set2.add("aa");
        set2.add("cc");
        for (Object o : set2) {
            System.out.println(o);
        }

Queue

队列,先进先出
在这里插入图片描述
在这里插入图片描述

PriorityQueue

PriorityQueue实现了一个优先队列:从队首获取元素时,总是获取优先级最高的元素。

底层是 数组+二叉树

参考资料

  • https://blog.csdn.net/u011485472/article/details/109573306

PriorityQueue默认按元素比较的顺序排序(必须实现Comparable接口),也可以通过Comparator自定义排序算法(元素就不必实现Comparable接口)。

public class Main {
    public static void main(String[] args) {
        Queue<String> q = new PriorityQueue<>();
        // 添加3个元素到队列:
        q.offer("apple");
        q.offer("pear");
        q.offer("banana");
        System.out.println(q.poll()); // apple
        System.out.println(q.poll()); // banana
        System.out.println(q.poll()); // pear
        System.out.println(q.poll()); // null,因为队列为空
    }
}

自定义Comparator

public class Main {
    public static void main(String[] args) {
        Queue<User> q = new PriorityQueue<>(new UserComparator());
        // 添加3个元素到队列:
        q.offer(new User("Bob", "A1"));
        q.offer(new User("Alice", "A2"));
        q.offer(new User("Boss", "V1"));
        System.out.println(q.poll()); // Boss/V1
        System.out.println(q.poll()); // Bob/A1
        System.out.println(q.poll()); // Alice/A2
        System.out.println(q.poll()); // null,因为队列为空
    }
}

class UserComparator implements Comparator<User> {
    public int compare(User u1, User u2) {
        if (u1.number.charAt(0) == u2.number.charAt(0)) {
            // 如果两人的号都是A开头或者都是V开头,比较号的大小:
            return u1.number.compareTo(u2.number);
        }
        if (u1.number.charAt(0) == 'V') {
            // u1的号码是V开头,优先级高:
            return -1;
        } else {
            return 1;
        }
    }
}

class User {
    public final String name;
    public final String number;

    public User(String name, String number) {
        this.name = name;
        this.number = number;
    }

    public String toString() {
        return name + "/" + number;
    }
}

Deque

Java集合提供了接口Deque来实现一个双端队列,它的功能是:

既可以添加到队尾,也可以添加到队首;
既可以从队首获取,又可以从队尾获取。
在这里插入图片描述

参考资料
https://www.liaoxuefeng.com/wiki/1252599548343744/1265122668445536

ArrayQueue
LinkedList

LinkedList,它即是List,又是Queue,还是Deque。但是我们在使用的时候,总是用特定的接口来引用它,这是因为持有接口说明代码的抽象层次更高,而且接口本身定义的方法代表了特定的用途。

// 不推荐的写法:
LinkedList<String> d1 = new LinkedList<>();
d1.offerLast("z");
// 推荐的写法:
Deque<String> d2 = new LinkedList<>();
d2.offerLast("z");

可见面向抽象编程的一个原则就是:尽量持有接口,而不是具体的实现类。

区别

ArrayDeque与LinkList区别:

ArrayDeque:

  • 数组结构
  • 插入元素不能为null
  • 无法确定数据量时,后期扩容会影响效率

LinkList

  • 链表结构
  • 插入元素能为null
  • 无法确定数据量时,有更好表现

参考资料
二者区别

Iterator

遍历方式(3种)

package com.collection;

import java.util.ArrayList;

import java.util.Iterator;

//import java.util.Map;

//import java.util.Collection;

public class Collection_ {

    public static void main(String[] args) {

        ArrayList arrayList = new ArrayList();

        arrayList.add("huhu");

        arrayList.add(10);//add(new Integer(10))

        arrayList.add(true);

        //遍历数组的迭代器

        Iterator iterator = arrayList.iterator();

        while(iterator.hasNext()){//需要先判断是否有下一个元素

            Object next = iterator.next();

            System.out.println(next);

        }

        //当迭代器指向最后一个元素后,若想再次遍历要重置迭代器

        iterator =arrayList.iterator();

        while (iterator.hasNext()) {

            Object next =  iterator.next();

            System.out.println(next);

        }

        //foreach 的增强循环

        for (Object a:

             arrayList) {

            System.out.println(a);

        }

//for循环

for (int i = 0; i < arrayList.size(); i++) {

    System.out.println(arrayList.get(i));

}

    }

}

Map

在这里插入图片描述

  • 保存具有映射关系的数据,key-value(双列关系)

常用集合
HashMap,HashTable,Properties
在这里插入图片描述

常用方法

HashMap hashmap=new HashMap();

hashmap.put("no1","haha");

hashmap.put("no2","jiji");

//hashmap的key不能重复,可以为null,但只能有一个;无序

hashmap.put("no2","mama");//替换机制

//value可以重复,可以为null,可以有多个

hashmap.put("no3","haha");

hashmap.put(null,null);

//get传入key可以得到value

System.out.println(hashmap.get("no2"));

//remove

hashmap.remove("no1");

//size

System.out.println(hashmap.size());

//isEmpty

System.out.println(hashmap.isEmpty());

//clear

hashmap.clear();

//containsKey

hashmap.containsKey("no8");//false

System.out.println(hashmap);

遍历

EntrySet ,keySet,Values中都是保存的地址 为了方便遍历

KeySet只是建立了一个对于HashMapNode中key的引用,其他类似
Map.Entry是一个内部接口,HashMapNode实现了它

package com.map_;

import com.sun.media.sound.RIFFInvalidFormatException;

import java.util.*;

public class method_ {

    @SuppressWarnings({"all"})

    public static void main(String[] args) {

        HashMap hashmap=new HashMap();

        hashmap.put("no1","haha");

        hashmap.put("no2","jiji");

        hashmap.put("no3","haha");

        //第一组:遍历所有的 key

        Set keySet = hashmap.keySet();

        //(1) for增强循环

        for (Object key:

             keySet) {

            System.out.println(hashmap.get(key));

        }

       //(2) 迭代器

        Iterator iterator = keySet.iterator();

        while (iterator.hasNext()) {

            Object next =  iterator.next();

            System.out.println(hashmap.get(next));

        }

        //第二组: 遍历value

        Collection values = hashmap.values();

        //(1) for增强

        for (Object value:

             values) {

            System.out.println(value);

        }

        //(2)迭代器

        Iterator iterator1 = values.iterator();

        while (iterator1.hasNext()) {

            Object next =  iterator1.next();

            System.out.println(next);

        }

        //第三组: EntrySet 来获取kv

        Set set = hashmap.entrySet();

        //(1) for增强

        for (Object entry:

             set) {

            Map.Entry me=(Map.Entry)entry;//向下转型

            //只有Map.Entry 是public ,想要使用getkey() 必须转换成Map.Entry

            System.out.println(me.getKey());

            System.out.println(me.getValue());

            System.out.println(entry);

        }

        //(2) 迭代器

        Iterator iterator2 = set.iterator();

        while (iterator2.hasNext()) {

            Object next =  iterator2.next();

            Map.Entry me=(Map.Entry)next;//向下转型

            System.out.println(((Map.Entry<?, ?>) next).getKey());

            System.out.println(me.getValue());

            System.out.println(next);

        }

    }

}

HashMap

  • key不能重复,value可以重复
  • 允许使用null键和null值
  • 如果添加相同的key,则会覆盖原来的;等同于修改,key不变,value变
  • 底层是Hash表,不能保证映射的顺序
  • 线程不安全
  • key和value可以保存任意类型的数据,会保存在HashMap$Node中、key常用字符串

对于HashSet,底层就是HashMap,key就是值,Value是一个常量

HashTable

在这里插入图片描述
对比
在这里插入图片描述

Properties

  • Properties类继承自 Hashtable类并且实现了Map接口,也是使用一种键值对的形式来保有数据。
  • 他的使用特点和 Hashtable类似
  • Properties还可以用于从xw. properties文件中,加数据到 Properties类对象并进行读和修改
  • key不能为null

工作后xx. properties文件通常作为配置文件

 Properties properties = new Properties();//创建对象
        // 加载配置文件
        properties.load(new FileReader("D:\\IDEA_file\\Learn_8\\src\\file\\mysql.properties"));
        //或者new
        properties.put("name","gao");
        properties.remove("name");
        //把k-v显示到控制台
        properties.list(System.out);
        String myuser=properties.getProperty("user");
        String mypsd=properties.getProperty("password");
        System.out.println(mypsd);
        //如果该文件没有该键值对,就创建,有就修改
        properties.setProperty("user2","tom");
        //指定存储位置
        properties.store(new FileWriter("D:\\IDEA_file\\Learn_8\\src\\file\\mysql.properties"),null);

mysql.properties

#Thu Feb 24 23:00:28 CST 2022
user=root
password=19790116
user2=tom
ip=192.168.200.1

工具类

java.util.collections
有许多静态方法

ArrayList<String> list = new ArrayList<>();
        list.add("aa");
        list.add("cc");
        list.add("aa");
        list.add("dd");
        for (Object o : list) {
            System.out.print(o+",");
        }
        System.out.println();
        //反转
        Collections.reverse(list);
        for (Object o : list) {
            System.out.print(o+",");
        }
        System.out.println();
        //排序
        Collections.sort(list);//等价于 list.sort(String::compareTo);
        for (Object o : list) {
            System.out.print(o+",");
        }
        System.out.println();
        //统计频率
        int count = Collections.frequency(list, "aa");
        System.out.println(count);
        //打乱
        Collections.shuffle(list);
        for (Object o : list) {
            System.out.print(o+",");
        }
        System.out.println();
        //交换
        Collections.swap(list,0,1);
        for (Object o : list) {
            System.out.print(o+",");
        }
        System.out.println();
        //最大值
        String max = Collections.max(list);
        System.out.println(max);
        //复制
        //替换
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值