单列集合Collection接口
- List :有序、可重复 ==> ArrayList、LinkedList、Vector
- Set:无序、不可重复 ==> HashSet、LinkedHashSet、TreeSet
Collection接口常用方法
- 前提:向Collection接口实现类中add数据obj时,obj所在类一定要重写equals(),直接Lombok
============================当前集合被修改===========================
对象.add(Object o);
对象.addAll(Collection coll); //把coll里所有元素添加到集合对象中
对象.clear(); //清空集合数据 size=0
对象.remove(Object o); //如果集合含至少1个o,则移除1个
对象.removeAll(Collection coll); //如果集合对象中包含co11元素,则移除所有该元素
对象.retailnAll(Collection coll); //获取交集,原集合只剩交集部分
对象.toArray(); //集合转化为数组
Arrays.asList(传入一个数组); //数组转化为集合
Arrays.asList(new int[]{1,2,3,4}),new int[]{1,2,3,4}会被当成一个元素
Arrays.asList(1,2,3,5)
Arrays.asList("a","b","c","d")
Arrays.asList(new Integer[]{1,2,3,4}) //new 包装类
============================当前集合不会修改===========================
对象.size();
对象.isEmpty(); //size==0
对象.contains(Object o);
//源码:equals(o),按内容判断。
//如果o重写了equals() 和 hashCode(),比较内容,否则 ,比较哈希值
对象.containsAll(Collection coll); //判断coll所有元素是否全在集合对象里面
对象.equals(Collection coll);
//因为List集合有序,所以除了比较元素内容是否一致之外,还要比各元素顺序是否一致
//如果是Set集合(无序),只需要比较元素内容
对象.iterator() 返回Iterator接口实例,用于遍历集合元素
-
Collection集合遍历
- 1、迭代器Iterator
public static void main(String[] args) {
Collection coll = new ArrayList();
coll.add(123);
coll.add(124);
//获取迭代器
Iterator it = coll.iterator();
//(1)遍历Collection集合
while(it.hasNext()){//it.hasNext()判断是否还有下一个元素
//it.next() :后移动一位,并取出元素
System.out.println(it.next());
}
//一定要重新获取iterator
it = coll.iterator();
//(2)移除不想要的元素
while(it.hasNext()){
Object obj = it.next();
if("hello".equals(obj)){
it.remove(); //移除当前位置元素
}
}
}
- 2、Foreach增强fro 本质还是迭代器
Collection coll = new ArrayList();
coll.add(123);
coll.add(124);
//遍历Collection集合,快捷键coll.iter回车
for (Object o : coll) {
System.out.println(o);
}
动态数组 :List接口( 有序,可重复 )
List接口常用接口
ArrayList list = new ArrayList();
list.add(int index,element e);
list.get(int index); //获取指定位置元素
//因为ArrayList底层是数组,所以下标索引从零开始。在下标为index位置插入e,后面元素后移一位
list.addAll(Collection coll); //把coll所有元素添加进list集合
list.add(Collection coll); //把coll集合当成一个元素,添加到集合中
list.indexOf(Object obj); //返回obj在集合中首次出现的位置,否则返回-1
list.lastIndexOf(Object obj); //返回obj在集合中最后一次出现的位置
list.remove(int index); //重载方法,不是重写,所以调用删除指定索引或者指定值看左边是谁,删除指定位置元素
list.set(int index,element e); //修改元素
====================集合改变===============================
List subList = list.subList(2,4); //左闭右开,获取下标为2,3的元素并存储到一个新集合中
面试题:[1,2]
ArrayList:List接口主要实现类;线程不安全,效率高;底层Object[]存储,查询快,增删慢
LinkedList:底层使用双向链表存储;增删快,查询慢
Vector:List接口古老实现类;线程安全,效率低;底层Object[]存储
面试题:ArrayList、LinkedList、Vector 三者区别
相同:都实现了List接口,存储数据特点一样:有序,可重复
不同:
ArrayList:List接口主要实现类;线程不安全,效率高;底层Object[]存储,查询快,增删慢
LinkedList:底层使用双向链表存储;增删快,查询慢
Vector:List接口古老实现类;线程安全,效率低;底层Object[]存储
Set接口( 无序,不可重复 )用的比较少,没有额外方法,存放元素重写hashCode和equals
- 无序性 :不等于随机性,而是按照hashCode值进行散列排序放进数组
- 不可重复性 :添加元素先判断哈希值是否一样,不一样直接添加进去,一样(哈希冲突)时,equals()判断内容是否一样,不一样则添加。
先hashCode,再equals();计算hashCode是根据成员来算的,下面有一道经典的面试题
https://www.bilibili.com/video/BV1Kb411W75N?p=547&spm_id_from=pageDriver
HashSet :Set接口的主要实现类;底层:数组+链表;线程不安全;可以存储null值
LinkedHashSet:作为HashSet的子类;"有序",实际上不是真正的有序,只是元素的数据结构是双向链表,所以知道插入顺序,适用于:频繁的遍历操作
(了解)TreeSet : 可以按照添加对象的指定属性,进行排序。
- 向TreeSet中添加数据,要求是相同类对象,类必须实现Comparable接口。不能添加不同类对象。
1、自然排序(实现comParable接口):comparTo()返回0,说明两对象相同
public class User implements Comparable<User> {
@Override
public int compareTo(User o) {
//按姓名排,反过来排return -this.Name.compareTo(user.Name);
int compare = this.Name.compareTo(o.Name);
if(compare!=0)
{
return compare;
}else{
//当姓名一样时,比较年龄Integer比较
return Integer.compare(this.age,o.age);
}
}
}
2、定制排序(Comparator):
public class Test05 {
public static void main(String[] args) {
Comparator<User> com = new Comparator<User>() {
@Override
public int compare(User u1, User u2) {
//年龄升序,如果age一样,姓名倒序
int result = Integer.compare(u1.getAge(),u2.getAge());
if(result==0){
result = -u1.getName().compareTo(u2.getName());
}
return result;
}
};
TreeSet<User> set = new TreeSet<>(com);
set.add(new User("李四",14));
set.add(new User("王五",20));
set.add(new User("赵六",16));
for (User user : set) {
System.out.println(user);
}
}
}
双列集合Map接口
- Map结构的理解:
key :由Set存储,因为不可重复、无序,=
value :由Collenction存储,可重复、无序
Entry :key+value,不重复、无序、put相同key时value可覆盖
Map实际存的元素就是Entry。
- ==> key存放的类要重写 hashCode()和equals(),除了TreeMap:自然排序和定制排序
- ==> value存放的类要重写 equals()
一个key对应一个value,多个key可以对应同一个value,例如学生-成绩
HashMap、LinkedHashMap、TreeMap、Hashtable、Properties
HashMap :作为Map的主要实现类;线程不安全,效率高,可存储null的key和value
LinkedHashMap :保证在遍历map元素时,可以按照添加的顺序实现遍历;类似LinkedHashSet,适用于频繁的遍历操作
HashMap和LinkedHashMap底层:数组+链表+红黑树(jdk8)
TreeMap :类似TreeSet,可以保证按照添加的键值对进行排序;实现排序遍历。
TreeSet和TreeMap底层都是红黑树
向TreeMap中添加key-value,要求key必须是由同一个类创建的对象
因为要按照key排序,自然排序、定制排序
Hashtable :古老实现类,线程安全,效率低,不能存储null的key和value
Properties :配置文件,key vlaue 都是String类型
面试题
- HashMap底层原理
jdk7
jdk8变化
-
HashMap和Hashtable的异同
-
CurrentHashMap 分段锁机制,适用于高并发
Map接口常用方法
//增删改操作
map.put(Object key,Object value) //key一般是String类型,key相同时,覆盖原有value
map.putAll(Map m);//将m集合中所有key-value对存放进当前map中
map.remove(Object key)
map.clear();//清空
//元素查询操作
map.get(Object key)
boolean map.containsKey(Object key)
boolean map.containsValue(Object value)
map.size()
map.isEmpty()
map.equals(Object obj); //判断两个map是否一样
//遍历方法
Set set = map.keySet();
Collection values = map.values();
Set set = map.entrySet();
遍历
public class Test06 {
public static void main(String[] args) {
HashMap map = new HashMap();
map.put("A",11);
map.put("B",12);
map.put("C",13);
map.put("D",14);
//遍历key
Set set01 = map.keySet();
for (Object o : set01) {
System.out.println(o);
}
//遍历value
Collection values = map.values();
for (Object value : values) {
System.out.println(value);
}
//遍历Map操作
Set set = map.entrySet();
for (Object o : set) {
//强转为Entry
Map.Entry entry = (Map.Entry)o;
System.out.println(entry.getKey()+" : "+entry.getValue());
}
}
}
操作Set、List、Map的集合工具类Collections
- 1、排序操作,均为static方法
=============================集合被修改====================================
reverse(List) :反转List中元素的顺序
shuffle(List) :打乱List集合顺序,进行随机排序
sort(List) :根据元素的自然排序对指定List集合元素按升序排序
sort(List,Comparator) :根据指定Comparator产生的顺序对List集合元素进行排序
swap(List,int,int) :将指定list集合中的i处元素和j处元素进行交换
- 其他操作
max(Collection) :按自然排序,获取最大值
max(Collection,Comparator) :按定制排序,获取最大值
min(Collection) :按自然排序,获取最大值
min(Collection,Comparator) :按定制排序,获取最大值
int frequency(Collection,Object) :返回指定元素的出现次数
void copy(List a,List b) :a的size()不能小于b的size(),将b的内容复制到a中
List a = Arrays.asList(new Object[List.size()]);
Collection.copy(a,b);
boolean replaceAll(List list,Object a,Object b) :
返回一个线程安全的Xxx