List和Set集合
一. List集合
1.1 List接口介绍
java.util.List
接口继承自Collection
接口,是单列集合的一个重要分支。
java.util.List接口 extends Collection接口
List接口的特点:
1.有序的集合,存储元素和取出元素的顺序是一致的(存储123 取出123) 。
2.有索引,可通过索引操作集合,包含一些带索引的方法 。
3.允许存储重复的元素,通过元素的equals方法,来比较是否为重复的元素。
1.2 List接口中常用方法
-public void add(int index,E element);将指定的元素添加到集合指定位置上
-public E get(int index); 返回集合中指定位置的元素
-public E remove(int index); 移除列表中指定位置的元素,返回被移除的元素
-public E set(int index,E element);用指定元素替换集合中指定位置的元素,返回被替换的元素
1.3 List集合的子类
java.util.LinkedList集合 implements List接口
LinkedList集合特点:
1.底层是链表结构:查询慢,增删快
2.里面包含大量操作首尾元素的方法
注意:使用LinkedList集合特有的方法,不能使用多态
-public void addFirst(E e);将指定元素插入此列表的开头
-public void addLastE e);将指定元素插入此列表的末尾
-public void push(E e); 将此元素推入此列表所表示的堆栈 等同于addFirst
-public E getFirst(); 返回此列表的第一个元素
-public E getLast(); 返回此列表的最后一个元素
-public E removeFirst();移除并返回此列表第一个元素
-public E removeLast();移除并返回此列表最后一个元素
-public E pop(); 从此列表所表示的堆栈处弹出一个元素 等同于removeFirst
-public boolean isEmpty(); 判断列表是否为空
二. Set集合
java.util.Set
接口继承自Collection
接口, 与Collection
接口中的方法基本一致 。
Set集合取出元素的方式可以采用:迭代器、增强for。
Set接口的特点:
1.不允许存储重复的元素
2.没有索引
2.1 HashSet集合
java.util.HashSet集合 implements Set接口
HashSet
是根据对象的哈希值来确定元素在集合中的存储位置,因此具有良好的存取和查找性能。保证元素唯一性的方式依赖于:hashCode
与equals
方法。
HashSet特点:
1.不允许存储重复元素
2.没有索引,没有带索引的方法,也没有for循环遍历
3.是一个无序的集合,存储元素和取出元素的顺序有可能不一致
4.底层是一个哈希表(查询速度非常快)
Set<Integer> set = new HashSet<>(); //多态
//使用add方法往集合中添加元素
set.add(1);
set.add(3);
set.add(2);
set.add(1);
//使用迭代器遍历set集合
Iterator<Integer> it = set.iterator();
while(it.hasNext()){
Integer n = it.next();
System.out.println(n); //1,2,3 不允许存储重复元素,无序
}
//增强for遍历set集合
for(Integer n:set){
System.out.print(n);
}
2.2 HashSet集合存储结构(哈希表)
在JDK1.8之前,哈希表底层采用数组+链表实现,即使用链表处理哈希冲突,同一hash值的链表都存储在一个链表里。但是当hash值相等的元素较多时,通过key值在链表中依次查找的效率较低。JDK1.8中,哈希表存储采用数组+链表+红黑树实现,当链表长度超过(8)时,将链表转换为红黑树,这样大大减少了查找时间。
在Object类有一个方法,可以获取对象的哈希值
int hashCode() 返回该对象的哈希码值
hashCode方法的源码:
public native int hashCode();
native:代表该方法调用的是本地操作系统的方法
要保证HashSet集合元素的唯一,就必须复写hashCode和equals方法建立属于当前对象的比较方式。
2.3 HashSet存储自定义类型元素
给HashSet中存放自定义类型元素时,需要重写对象中的hashCode和equals方法,建立此对象的属性比较方式,才能保证HashSet集合中的对象唯一 。
public class Person {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public boolean equals(Object o) { //重写equals方法
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Person person = (Person) o;
return age == person.age && name.equals(person.name); //针对Person对象的属性比较是否相同对象
}
@Override
public int hashCode() { //重写hashCode方法
return Objects.hash(name, age); //比较两个对象属性的哈希值是否一样
}
//创建一个HashSet集合存储Person
HashSet<Person> set = new HashSet<>();
Person p1 = new Person("乔丹",35);
Person p2 = new Person("乔丹",35);
Person p3 = new Person("乔丹",42);
set.add(p1);
set.add(p2); //添加失败,集合中已经有 "乔丹",35
set.add(p3);
System.out.println(set);
2.4 LinkedHashSet
java.util.LinkedHashSet集合 extends HashSet集合
LinkedHashSet集合特点:
底层是一个哈希表(数组+链表/红黑树)+链表:多了一条链表(记录元素的存储顺序)保证了元素有序。
HashSet<String> set = new HashSet<>();
set.add("jordan");
set.add("abc");
set.add("abc");
set.add("air");
System.out.println(set); //[abc, jordan, air] 无序的 不允许重复
LinkedHashSet<String> linked = new LinkedHashSet<>();
linked.add("jordan");
linked.add("abc");
linked.add("abc");
linked.add("air");
System.out.println(linked); //[jordan, abc, air] 有序的 不允许重复