Java SE(八)之集合基础入门(Collection,ArrayList,HashSet,HashMap)


开局一张图:整个集合大家庭!

在这里插入图片描述

Collection

是单例集合的顶层接口,它表示一组对象,这些对象也称为Collection的元素。JDK不提供此接口的任何直接实现。Collection主要包括List和Set。

创建Collection集合的对象:

  • 多态的方式
  • 具体实现类如 ArrayList 等

1.常用方法

有一些增删查改的方法

方法含义
boolean add(E e)添加元素
boolean remove(object o)从集合中移除指定元素
void clear( )清除集合中的元素
boolean contains(Object o)判断集合中是否存在指定的元素
boolean isEmpty( )判断集合是否为空
int size()集合的长度

2.遍历

(为方便后面演示,首先新建一个Collection集合,再往里面添加元素)

Collection<String> sites = new ArrayList<String>();
sites.add("Google");
sites.add("baidu");
sites.add("Taobao");

(注意多态的创建方法,sites对象调用方法时编译看左边,运行看右边,这样就用不了子类特有方法,参考链接:实现和继承时的java多态)

(1)for循环

// 常规的写法
for(int i=0;i<sites.size();i++) {
        // get()是List接口定义,ArrayList实现的方法
        System.out.println(sites.get(i));
}

(2)Iterator

Iterator对象称为迭代器,主要用于遍历Collection集合中的元素。它不是一个集合,仅用于遍历集合

所有实现了Collection接口的集合类都有一个iterator()方法(通过集合对象去调用iterator()方法),用以返回Iterator接口的对象。

Iterator iterator() :返回此集合的迭代器,通过集合的iterator()方法得到
Iterator iterator = coll.iterator() (coll是集合的对象)

主要方法:

方法含义
boolean hasNext()检测集合中是否还有元素
E next()返回迭代器的下一个元素,并且更新迭代器的状态
void remove()将迭代器返回的元素删除

先用hasNext()方法判断,再调用next()方法

// 创建集合 sites 的迭代器
Iterator<String> it = sites.iterator();

// 通过对象it的next方法,输出集合中的第一个元素
System.out.println(it.next());

// 先判断集合中是否还有元素,如果有,进行遍历
while(it.hasNext())
{
    String s = it.next();
    System.out.println(s);
}

(3)增强for循环

  • 实现Iterable接口的类允许其对象成为增强型for语句的目标;
  • 内部原理是个Iterator迭代器(简化版的Iterator);
  • 简化数组和Collection集合的遍历

格式:

for(元素数据类型 变量名:数组或Collection集合)
{
// 使用变量,变量即元素!
}

// s 即 sites 中的元素
for (String s : sites) {
       System.out.println(s);
}

3.List

特点:

  • 是一个接口,继承自Collection,不能实例化,需要具体类来实例化;
  • List 集合中的对象有序(添加顺序和取出顺序一致),且可重复
  • List集合每一个元素都有其对应的顺序索引,可以通过整数索引访问元素(丰富了Collection方法)

List 接口常用实现类有:ArrayList(实现动态数组),Vector(实现动态数组)LinkedList(实现链表),Stack(实现堆栈)。

相比Collection增加的方法(List特有方法):

方法含义
void add(int index,E e)【增】在此集合的指定位置插入指定元素
E remove(int index)【删】删除指定索引处的元素,返回被删除的元素
E set(int index,E e)【改】修改指定索引处的元素,返回被修改的元素
E get(int index)【查】返回指定索引处的元素
int indexOf(Object o)返回此列表中指定元素的第一次出现的索引

(方法演示见下面的ArrayList)

特有遍历——列表迭代器 ListIterator,

  • 通过List集合的ListIterator得到,ListIterator<E> listIterator()
  • 允许程序沿任一方向遍历列表的列表迭代器,在迭代期间修改列表,并获取列表中迭代器的当前位置。
  • 主要方法
方法含义
E next()返回迭代器的下一个元素
boolean hasNext()检测集合中是否还有元素
E previous()返回迭代器的上一个元素
void add(E e)将指定元素插入列表

(1)ArrayList

特点:

  • ArrayList 类实现一个可增长的动态数组,它可以存储不同类型的对象(包括 null 在内),而数组只能存放特定数据类型的值。

  • ArrayList 实现了 List 接口,底层数据结构是数组,查询快,增删慢。存储类型只能存储引用数据类型

定义形式:

// E: 泛型数据类型,用于设置 objectName 的数据类型
ArrayList<E> objectName =new ArrayList<>();  // 初始化

常用方法:
实现了List接口的方法,没有太多特有方法,这里直接代码演示:

 //创建集合
 ArrayList<String> list = new ArrayList<>();

 //public boolean add(E e):添加元素,返回是否添加成功
 list.add("apple");
 list.add("pear");
 list.add("apple"); // 注意集合具有无序 可重复性
 list.add("watermelon");

 //输出集合
 System.out.println("list:" + list); //输出 list:[apple, pear, apple, watermelon] 

 //public int size():返回集合中的元素的个数
 System.out.println("集合的长度是:"+list.size()); // 输出:集合的长度是:4

增删查改:

 /*public E set(int index,E element):修改指定索引处的元素,返回被修改的元素*/
 
  System.out.println(list.set(1,"grape"));  // 输出pear
  //System.out.println(list.set(3,"hello"));  // 越界错误

  /*public E get(int index):返回指定索引处的元素*/
  System.out.println(list.get(1));  // 输出grape

 /*public boolean remove(Object o):删除指定的元素,返回删除是否成功*/
  System.out.println(list.remove("apple"));  // 输出true
  System.out.println(list.remove("hello"));   // 输出false

  System.out.println("list:" + list);// 输出:list:[grape, apple, watermelon]

  /*public E remove(int index):删除指定索引处的元素,返回被删除的元素*/ 
  System.out.println(list.remove(1)); // 输出apple

ArrayList基本概念和方法使用基本就是这样,进一步可以参考ArrayList源码分析,可以看到底层扩容原理

(2)LinkedList

特点:

  • LinkedList底层维护了一个双向链表,查询慢,增删快;
  • LinkedList中维护了两个属性first和last,分别指向首节点和尾节点;
  • 可作为队列使用,可进行列表的相关操作

实现的接口和继承的类如下:

相对于List的一些特有功能:

方法含义
void addFirst(E e)在该列表开头插入指定的元素
void addLast(E e)指定元素追加到此列表的末尾
E getFirst()返回该列表中的第一个元素
E getlast()返回该列表中的最后一个元素
E removeFirst()从列表中删除并返回第一个元素
E removeLast()从列表中删除并返回最后一个元素

(3)两个实现类的比较

底层结构增删效率改查效率
ArrayList可变数组较低,通过数组扩容较高
LinkedList双向链表较高,通过链表追加较低

4.Set

特点:

  • Set 的元素是无序的(添加和取出的顺序不一致)
  • Set 不包含重复元素的 collection,则最多包含一个null
  • Set集合没有带索引的方法,不能用普通for循环遍历(迭代器,增强for)

Set中的方法和Collection中的类似。

(1)HashSet

特点:

  • 底层数据结构是哈希表
  • 对集合的迭代顺序不作任何保证(不保证存储和取出的元素顺序一致)
  • 没有带索引的方法,所以不能使用普通for循环遍历
  • 由于是Set集合,所以是不包含重复元素的集合

定义:

HashSet<String> sites = new HashSet<String>();

代码演示:

// "static void main" must be defined in a public class.
public class Main {
    public static void main(String[] args) {
        // 1. initialize the hash set
        Set<Integer> hashSet = new HashSet<>();     
        // 2. add a new key
        hashSet.add(3);
        hashSet.add(2);
        hashSet.add(1);
        // 3. remove the key
        hashSet.remove(2);        
        // 4. check if the key is in the hash set
        if (!hashSet.contains(2)) {
            System.out.println("Key 2 is not in the hash set.");
        }
        // 5. get the size of the hash set
        System.out.println("The size of has set is: " + hashSet.size());     
        // 6. iterate the hash set
        for (Integer i : hashSet) {
            System.out.print(i + " ");
        }
        System.out.println("are in the hash set.");
        // 7. clear the hash set
        hashSet.clear();
        // 8. check if the hash set is empty
        if (hashSet.isEmpty()) {
            System.out.println("hash set is empty now!");
        }
    }
}

介绍一下哈希值:
哈希值是jdk根据对象的地址字符串数字计算出来的int类型的数值。

Object类中的方法:
public int hashCode():返回对象的哈希值

String s="hello";
System.out.println(s.hashCode());

Student std = new Student();
System.out.println(std.hashCode());

99162322
1784662007

一般来说,不同对象的哈希值是不同的,但是可以通过方法重写使不同对象的哈希值相同。

哈希表

jdk8以前,底层采用数组+链表实现,可以看作一个元素为链表的数组

在这里插入图片描述

关于HashSet更深入的底层原理,请参见 HashSet底层原理

(2)TresSet

Map

Interface Map<K,V> K:键的类型,V:值的类型

将键映射到值的对象,Map中的key不允许重复(原因和HashSet一样)不能包含重复的键,value可以重复。每个键可以映射到最多一个值。

创建Map集合的对象

  • 多态的方式
  • 具体实现类如HashMap

1.Map的常用方法

基本功能

方法含义
V put(K key,V value)添加元素
V remove(Object key)根据键删除键值对元素
void clear()移除所有的键值对元素
boolean containsKey(Object key)判断集合是否包含指定的键
boolean containsValue(Object value)判断集合是否包含指定的值
boolean isEmpty()判断集合是否为空
int size()集合的长度

获取功能

方法含义
V get(Object key)根据键获取值
V getOrDefault(Object key, V defaultValue)获取key的value,如果不存在,就得到默认值
Set keySet()获取所有键的集合
Collection values()获取所有值的集合
Set<Map.Entry<K,V>> entrySet()获取所有键值对对象的集合

2.遍历

因为Map存储的元素都是成对出现的,将Map看成一个“夫妻对”的集合

方式1

遍历思路:先把所有的丈夫给集中起来;然后遍历丈夫的集合,获取到每一个丈夫;最后根据丈夫去找对应的妻子

步骤:

  • 获取所有键的集合,用keySet()方法实现
  • 遍历键的集合,获取到每一个键
  • 根据键去找值,用get(Object key)方法实现

方式2

遍历思路:先获取所有“结婚证”的集合,然后遍历结婚证的集合,得到每一个结婚证,最后根据结婚证获取丈夫和妻子

步骤:

  • 获取所有键值对对象的集合
    • Set<Map.Entry<K,V>> entrySet():获取所有键值对对象的集合
  • 遍历键值对对象的集合,得到每一个键值对对象
    • 用增强for实现,得到每一个Map.Entry
  • 根据键值对对象获取键和值
    • 用getKey()得到键
    • 用getValue()得到值

3.HashMap

以一个例子熟悉一下方法:

public static void main(String[] args) {
    // 1. initialize a hash map
    Map<Integer, String> hashmap = new HashMap<>();

    // 2. insert a new (key, value) pair or update the value of existed key
    hashmap.put(201, "张三");
    hashmap.put(202"李四");
    hashmap.put(203, "王五");
    hashmap.put(201, "赵六"); // 注意此时key重复了,不会被添加到hashmap中

    // 4. get the value of specific key
    System.out.println("The value of key 201 is: " + hashmap.get(1));

    // 5. delete a key
    hashmap.remove(202);

    // 6. check if a key is in the hash map
    if (!hashmap.containsKey(202)) {
        System.out.println("Key 2 is not in the hash map.");
    }

    // 7. get the size of the hash map
    System.out.println("The size of hash map is: " + hashmap.size());

    // iterate the hash map
    // 8-1 获取所有键的集合。用keySet()方法实现
        Set<String> keySet = hashmap.keySet();
        //遍历键的集合,获取到每一个键。用增强for实现
        for (String key : keySet) {
            //根据键去找值。用get(Object key)方法实现
            String value = hashmap.get(key);
            System.out.println(key + "," + value);
        }
     // 8-2 获取所有键值对对象的集合
      Set<Map.Entry<Integer, String>> entrySet = hashmap.entrySet();
      //遍历键值对对象的集合,得到每一个键值对对象
       for (Map.Entry<Integer, String> me : entrySet) {
          //根据键值对对象获取键和值
           String key = me.getKey();
           String value = me.getValue();
           System.out.println(key + "," + value);
        }

    // 9. clear the hash map
    hashmap.clear();

    // 10. check if the hash map is empty
    if (hashmap.isEmpty()) {
        System.out.println("hash map is empty now!");
    }
}
}

关于HashMap的底层原理,请参见: HashMap源码分析

4.TreeMap

Collections

此类完全由在 collection 上进行操作或返回 collection 的静态方法组成。它包含在 collection 上操作的多态算法,即“包装器”,包装器返回由指定 collection 支持的新 collection,以及少数其他内容。即相当于Array与Arrays类,都是工具类,用来操作相应的容器。

常用方法:

方法含义
reverse(List)反转List中元素的顺序
shuffle(List)打乱List中元素的顺序
sort(List)对List中元素进行排序
swap(List,int,int)交换list中的两处元素
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值