抱歉,您的浏览器无法访问本站
本页面需要浏览器支持(启用)JavaScript
了解详情 >

集合框架

ArrayList类

容器概念

我们已经知道,如果要存放多个对象,可以使用数组,但是数组有局限性,比如:

声明长度是10的数组,不用的数组就浪费了,超过10的个数,又放不下

为了解决数组的局限性,引入容器类的概念。 最常见的容器类就是ArrayList容器的容量"capacity"会随着对象的增加,自动增长,只需要不断往容器里增加英雄即可,不用担心会出现数组的边界问题。

使用ArrayList前需导入:

1
import java.util.ArrayList;
1
2
3
4
5
6
7
8
//容器类ArrayList,用于存放对象
ArrayList heros = new ArrayList();
heros.add( new Hero("盖伦"));
System.out.println(heros.size());

//容器的容量"capacity"会随着对象的增加,自动增长
//只需要不断往容器里增加英雄即可,不用担心会出现数组的边界问题。
heros.add( new Hero("提莫"));

ArrayList常用方法

关键字 简介 示例代码
add 增加 示例代码
contains 判断是否存在 示例代码
get 获取指定位置的对象 示例代码
indexOf 获取对象所处的位置 示例代码
remove 删除 示例代码
set 替换 示例代码
size 获取大小 示例代码
toArray 转换为数组 示例代码
addAll 把另一个容器所有对象都加进来 示例代码
clear 清空 示例代码
  • add
    1
    2
    3
    4
    5
    for (int i = 0; i < 5; i++) {
    heros.add(new Hero("hero " + i));
    }
    Hero specialHero = new Hero("special hero");
    heros.add(specialHero);
  • contains
    1
    2
    3
    4
    // 初始化5个对象
    System.out.println(heros); //打印heros
    System.out.println(heros.contains(new Hero("hero 1"))); //false
    System.out.println(heros.contains(specialHero)); //true
  • get

    通过get获取指定位置的对象,如果输入的下标越界,一样会报错

    1
    2
    3
    System.out.println(heros.get(5)); //获取指定位置的对象

    System.out.println(heros.get(6)); //如果超出了范围,依然会报错
  • indexOf
    1
    2
    3
    System.out.println("specialHero所处的位置:"+heros.indexOf(specialHero));

    System.out.println("新英雄,但是名字是\"hero 1\"所处的位置:"+heros.indexOf(new Hero("hero 1")));
  • remove
    • remove可以根据下标删除ArrayList的元素

      1
      heros.remove(2);
    • 也可以根据对象删除

      1
      heros.remove(specialHero);
  • set

    set用于替换指定位置的元素

    1
    heros.set(5, new Hero("hero 5"));
  • size

    size 用于获取ArrayList的大小

    1
    System.out.println(heros.size());
  • toArray

    toArray可以把一个ArrayList对象转换为数组。
    需要注意的是,如果要转换为一个Hero数组,那么需要传递一个Hero数组类型的对象给toArray(),这样toArray方法才知道,你希望转换为哪种类型的数组,否则只能转换为Object数组

    1
    2
    Hero hs[] = (Hero[])heros.toArray(new Hero[]{});
    //传递一个Hero数组类型的对象new Hero[]{}给toArray()
  • addAll

    addAll 把另一个容器所有对象都加进来

    1
    2
    3
    4
    5
    ArrayList anotherHeros = new ArrayList();
    anotherHeros.add(new Hero("hero a"));
    anotherHeros.add(new Hero("hero b"));

    heros.addAll(anotherHeros);
  • clear

    clear 清空一个ArrayList

    1
    2
    heros.clear();
    System.out.println("ArrayList heros:\t" + heros);

List接口

  • ArrayList与List

    ArrayList实现了接口List,常见的写法会把引用声明为接口List类型

    注意:是java.util.List,而不是java.awt.List

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    package collection;

    import java.util.ArrayList;
    import java.util.List;

    import charactor.Hero;

    public class TestCollection {

    public static void main(String[] args) {
    //ArrayList实现了接口List

    //常见的写法会把引用声明为接口List类型
    //注意:是java.util.List,而不是java.awt.List
    //接口引用指向子类对象(多态)

    List heros = new ArrayList();
    heros.add( new Hero("盖伦"));
    System.out.println(heros.size());

    }

    }
  • List的接口与方法

    因为ArrayList实现了List接口,所以List接口的方法ArrayList都实现了。
    在【ArrayList常用方法】有详细的讲解,在此不作赘述

泛型

  • 不指定泛型的容器,可以存放任何类型的元素
  • 指定了泛型的容器,只能存放指定类型的元素以及其子类

语法:

1
2
3
4
List<Hero> genericheros = new ArrayList<Hero>(); //只能存放Hero类型

//简写
List<Hero> genericheros = new ArrayList<>();

遍历

关键字 简介 示例代码
for 用for循环遍历 示例代码
iterator 迭代器遍历 示例代码
增强型for 用增强型for循环 示例代码
  • for
    1
    2
    3
    4
    for (int i = 0; i < heros.size(); i++) {
    Hero h = heros.get(i);
    System.out.println(h);
    }
  • iterator

    Iterator 类位于 java.util 包中,使用前需要引入它,语法格式如下:

    1
    import java.util.Iterator; // 引入 Iterator 类

    迭代器的两个基本操作是 next 、hasNext 和 remove。

    • 调用 it.next() 会返回迭代器的下一个元素,并且更新迭代器的状态。

    • 调用 it.hasNext() 用于检测集合中是否还有元素。

    • 调用 it.remove() 将迭代器返回的元素删除。

    首先将集合转为迭代器

    1
    Iterator<Hero> it= heros.iterator();

    用while遍历

    1
    2
    3
    4
    5
    6
    //从最开始的位置判断"下一个"位置是否有数据
    while(it.hasNext()){ //判断是否为null

    Hero h = it.next(); //通过next取出来,并且把指针向下移动
    System.out.println(h);
    }

    用for遍历

    1
    2
    3
    4
    for (Iterator<Hero> iterator = heros.iterator(); iterator.hasNext();) {
    Hero hero = (Hero) iterator.next();
    System.out.println(hero);
    }
  • 增强型for
    1
    2
    3
    for (Hero h : heros) {
    System.out.println(h);
    }

其他集合

以下情况使用 ArrayList :

  • 频繁访问列表中的某一个元素。
  • 只需要在列表末尾进行添加和删除元素操作。

以下情况使用 LinkedList :

  • 你需要通过循环迭代来访问列表中的某些元素。
  • 需要频繁的在列表开头、中间、末尾等位置进行添加和删除元素操作。
1
2
3
4
5
6
//创建链表
import java.util.LinkList;

LinkedList<E> list = new LinkedList<E>(); // 普通创建方法
//或者
LinkedList<E> list = new LinkedList(Collection<? extends E> c); // 使用集合创建链表

常用方法:

插入:

  • addLast()
  • addFirst()

查看:

  • getFirst()
  • getLast()

删除:

  • removeFirst()
  • removeLast()

队列-Queue

Queue是先进先出队列 FIFO,常用方法:

  • offer(e) 在最后添加元素e
  • poll() 取出第一个元素
  • peek() 查看第一个元素

二叉树

二叉树由各种节点组成

二叉树特点:

  • 每个节点都可以有左子节点,右子节点
  • 每一个节点都有一个
image-20210212204447345
1
2
3
4
5
6
7
8
9
package collection;

public class Node {
public Node leftNode; // 左子节点

public Node rightNode; // 右子节点

public Object value; // 值
}

HashMap

  1. HashMap 是一个散列表,它存储的内容是键值对key-value映射;

  2. HashMap 实现了 Map 接口,根据键的 HashCode 值存储数据,具有很快的访问速度,最多允许一条记录的键为 null,不支持线程同步;

  3. HashMap 是无序的,即不会记录插入的顺序;

  4. HashMap中的key不能重复,value可以重复;

  5. HashMap 继承于AbstractMap,实现了 Map、Cloneable、java.io.Serializable 接口。

image-20210212205720886

创建一个 HashMap 对象 Sites,其中:

  • key为整型

  • value为字符串(String)类型

    1
    2
    3
    import java.util.HashMap; // 引入 HashMap 类

    HashMap<Integer, String> Sites = new HashMap<Integer, String>();

添加元素 put(key, value)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import java.util.HashMap;

public class HashMapTest {
public static void main(String[] args) {
// 创建 HashMap 对象 Sites
HashMap<Integer, String> Sites = new HashMap<Integer, String>();
// 添加键值对
Sites.put(1, "Google");
Sites.put(2, "Runoob");
Sites.put(3, "Taobao");
Sites.put(4, "Zhihu");
System.out.println(Sites);
}
}

访问元素的value值:get(key)

1
System.out.println(Sites.get(3));

删除元素(键值对):remove(key)

1
Sites.remove(4);

清空所有键值对:clear()

1
Sites.clear();

返回元素(键值对)数量:size()

1
Sites.size();

返回所有key:keySet()

1
Sites.keySet()

返回所有values:values()

1
Sites.values()

HashSet

  1. HashSet 基于 HashMap 来实现的,是一个不允许有重复元素的集合。
  2. HashSet 允许有 null 值。
  3. HashSet 是无序的,即不会记录插入的顺序。
  4. 由于Set是无序的,所以Set不可以获取指定位置的元素。
  5. HashSet 实现了 Set 接口。
image-20210212212148854

创建一个Set:

1
HashSet<String> sites = new HashSet<String>();
  • 添加元素:sites.add(e)
  • 判断元素e是否存在:sites.contains(e)
  • 删除元素:sites.remove(e)
  • 清空元素:sites.clear()
  • 计算大小:sites.size()

Collection

Collection是 Set、List、Queue、Deque的接口(Deque 继承 Queue,间接的继承了 Collection)

  • Queue: 先进先出队列
  • Deque: 双向链表

注:Collection 和 Map 之间没有关系,Collection是放一个一个对象的,Map 是放键值对的

Collections

Collections是一个类,容器的工具类,就如同Arrays是数组的工具类

Collections具有以下方法:

关键字 简介
reverse 反转
shuffle 混淆
sort 排序
swap 交换两个数据的位置
rotate 滚动
synchronizedList 线程安全化

创建一个集合numbers

1
2
3
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
1
2
3
4
5
List<Integer> numbers = new ArrayList<>();

for (int i = 0; i < 10; i++) {
numbers.add(i);
}
  • reverse:

    1
    Collections.reverse(numbers);
  • shuffle:

    1
    Collections.shuffle(numbers);
  • sort:

    1
    Collections.sort(numbers);
  • swap:

    1
    Collections.swap(numbers,0, 5);  //交换第0个和第5个元素
  • rotate:把List中的数据,向右滚动指定单位的长度

    1
    Collections.rotate(numbers,2);
  • synchronizedList:把非线程安全的List转换为线程安全的List

    1
    2
    3
    //把非线程安全的List转换为线程安全的List
    List<Integer> synchronizedNumbers = (List<Integer>) Collections.synchronizedList(numbers);

关系与区别

其他

评论