Java -- 集合(List,Set,Map)
Java的集合类就相当于一个容器,专门用来存放Java类的对象。集合和数组有些类似,但有时无法确定需要保存多少对象,数组用起来就不是很方便,因此我们需要一个特殊的类,用来保存数目不确定的对象。
集合按照其存储结构可分为两大类,单列集合Collection和双列集合Map,我们最常使用的List集合就是继承自Collection接口,它就是一个单列集合。
下面是总结的一个思维导图,仅供参考。
Collection接口
方法 | 功能描述 |
---|---|
boolean add(Object o) | 向集合中添加一个元素 |
boolean addAll(Collection c) | 将Collection中的所有元素添加到集合 |
void clear() | 清空集合,删除集合中的所有元素 |
boolean remove(Object o) | 删除集合中的指定元素 |
boolean removeAll(Collection c) | 删除指定集合中所有元素 |
boolean isEmpty() | 判断集合是否为空 |
int Size() | 获取集合中元素的个数 |
boolean contains(Object o) | 判断集合中是否包含某元素 |
List接口的方法(重点)
List集合的特点:线性存储,元素顺序有序,即元素的存放顺序和取出顺序一致,并且可以存放重复的元素。
List是一个接口;ArrayList(常用)、LinkedList、Vector都是List集合的实现类。
List继承了Collection的方法,并且新增了一些自己的方法:
方法 | 功能描述 |
---|---|
void add(int index,Object e) | 将元素e插入到index处 |
remove(int index) | 删除index索引处的元素 |
get(int index) | 返回至index索引处的元素 |
int indexOf(Object o) | 返回对象o的索引位置 |
int lastIndexOf(Object o) | 返回对象o的最后一次出现的索引位置 |
set(int index,Object e) | 将index处的元素替换为元素e |
List subList(int fromIndex, int toIndex); | 返回由索引fromIndex(包括)到toIndex(不包括)处的所有元素 |
下面是写的一个小例子,方便理解只使用了最常用的方法;
public static void main(String[] args) {
ArrayList<Object> list = new ArrayList<>();
list.add("1001");//添加元素
list.add("1002");
list.add("1003");
list.add("1001");
list.add("1005");
System.out.println(list);
System.out.println(list.size());//集合大小
System.out.println(list.indexOf("1001"));//1001出现下标
System.out.println(list.lastIndexOf("1001"));
System.out.println("---------------");
list.set(2,"1008");//下标从0开始,和数组类似
System.out.println(list);
System.out.println(list.get(1));//获取下标1处的元素
System.out.println(list.subList(1,3));//获取下标1-3(不包括)处的所有元素
}
/* 输出结果
[1001, 1002, 1003, 1001, 1005]
5
0
3
---------------
[1001, 1002, 1008, 1001, 1005]
1002
[1002, 1008]
*/
LinkedList也有一些自定义的方法,方便进行集合的操作:
方法 | 功能描述 |
---|---|
Object getFirst() | 获取第一个元素 |
Object getLast() | 获取最后一个元素 |
Object removeFirst() | 移出第一个元素 |
Object removeLast() | 移出最后一个元素 |
void addFirst(E e) | 将元素e添加到开头 |
void addLast(E e) | 将元素e添加到最后 |
Set接口
Set接口和List接口类似,都是继承自Collection接口,但Set接口并没有像List接口那样对Collection的方法进行扩充。Set中元素的存放是无序的,即存放的位置和取出的位置不一定相同,并且Set以一定的规则阻止元素的重复。
Set接口共有两个实现类
- HashSet :根据对象的哈希值进行确定存储位置。
- TreeSet :以二叉树的形式存取元素。
HashSet
HashSet的底层就是一个HashMap,使用HashMap来保存元素;下文有HashMap的具体解释。
private transient HashMap<E,Object> map;
public HashSet() {//HashSet一个无参构造,初始化HashMap
map = new HashMap<>();
}
add执行过程:当向HashSet中添加一个元素时,实现调用hashCode()方法来计算出一个哈希值来确定元素的存储位置然后去查找当前这个位置是否存在元素(将计算的哈希值作为HashMap的key进行存储,HashMap的key不允许重复具有唯一性,当插入相同的key时会返回false,原来的key保持不变),如果不存在元素直接将元素放入当前位置,如果存在元素,调用equals()方法进行比较,如果和当前元素相同就舍弃,不同则插入。
默认的只有String类进行了hashCode和equals方法的重写,但如果换做其他类如User类就会出现相同的学生信息,需要在User类中对hashCode和equals方法进行重写。
//为重写方法前
public static void main(String[] args) {
HashSet<Object> hashSet = new HashSet<>();
User user1 = new User(1,"张三");
User user2 = new User(2,"李四");
User user3 = new User(2,"张三");
User user5 = new User(4,"王五");
hashSet.add(user1);
hashSet.add(user2);
hashSet.add(user3);
hashSet.add(user5);
System.out.println(hashSet);
}
/*
[User{id=2, name='李四'}, User{id=4, name='王五'}, User{id=1, name='张三'}, User{id=1, name='张三'}]
*/
//重写方法 重写User类
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
User user = (User) o;
return id == user.id &&
Objects.equals(name, user.name);
}
@Override
public int hashCode() {
return Objects.hash(id);
}
/*结果
[User{id=1, name='张三'}, User{id=2, name='李四'}, User{id=4, name='王五'}]
*/
TreeSet
TreeSet的底层就是一个自平衡的二叉排序树,可以实现对每个元素进行排序并且保证元素不会出现重复;它是基于TreeMap进行实现的。
add执行过程:当插入第一个元素时,将元素放在根节点,插入第二个元素是,与根节点的元素进行比较,比它小的元素放在左子树,大的元素放在右子树,相同元素不插入;在二叉排序树中任一结点的左子树都小于结点的值,右子树都大于结点的值。
Iterator接口
Iterator接口也是Java集合框架中的一种,但与Collection类接口不同,Iterator接口主要用于迭代访问即遍历Collection中的元素。
Iterator<Object> iterator = list.iterator();//用于遍历Collection集合
while (iterator.hasNext())
{
System.out.println(iterator.next());
}
/*输出结果
1001
1002
1008
1001
1005
*/
Map接口
Map接口是一种双列集合,每个元素都由Key – Value即键值对组成,每一个key对应一个value,通过查找指定的key就能得到value值。
Map的通用方法
方法 | 功能描述 |
---|---|
void put(Object key,Object value) | 将指定值与指定键进行关联映射 |
Object get(Object key) | 返回key值对应的value |
boolean containsKey(Object key) | 集合中是否存在指定key,是则返回true,否则false |
boolean containsValue(Object value) | 集合中是否存在指定value,是则返回true,否则false |
HashMap
HashMap是Map接口的实现类,Key值不允许出现重复,插入重复键,value值会被覆盖。
HashMap就是数组和链表的一个结合体;以数组为底层,每一个数组又作为一个链表。
public static void main(String[] args) {
HashMap<Object, Object> hashMap = new HashMap<>();
hashMap.put("1","aaa");//插入数据 key -- value;key和value的值可以为null,key为null时将元素放在第一个
hashMap.put("3","bbb");
hashMap.put("2","ccc");
hashMap.put("4","ddd");
hashMap.put("","");//key -- value 为null
System.out.println("------运行结果---------");
System.out.println(hashMap);//打印输出
System.out.println(hashMap.get("2"));//获取指定key的value
System.out.println(hashMap.containsKey("2"));//集合中是否存在指定key 是则返回true,否则false
System.out.println(hashMap.containsValue("666"));//集合中是否存在指定value,是则返回true,否则false
hashMap.put("3","fff");
System.out.println(hashMap);//相同键,值覆盖
}
/*
------运行结果---------
{=,1=aaa, 2=ccc, 3=bbb, 4=ddd}
ccc
true
false
{=,1=aaa, 2=ccc, 3=fff, 4=ddd}
*/
TreeMap和TreeSet基本相似,TreeSet就是基于TreeMap实现的。
注:正在学习中,如有错漏欢迎指正,转载请注明出处。
推荐阅读