集合体系:
数组和集合的区别:
- (1): 长度区别:
数组的长度是固定的而集合的长度是可变的
(2): 存储数据类型的区别:
数组可以存储基本数据类型 , 也可以存储引用数据类型; 而集合只能存储引用数据类型
(3): 内容区别:
数组只能存储同种数据类型的元素 ,集合可以存储不同类型的元素
Collection:
顶层抽象接口
方法:
- 添加:
- boolean add(Object obj)
- boolean addAll(Collection c)
- 删除:
- void clear()
- boolean remove(Object o)
- boolean removeAll(Collection c)
- 判断:
- boolean contains(Object o)
- boolean containsAll(Collection c)
- boolean isEmpty()
- 获取:
- Iterator iterator()(Iterator是一个内部类,有hasnext(),next()方法)
//(无get,迭代器,遍历集合)
Iterator iterator=list1.iterator();
whlie(iterator.hasnext()){
Object next=iterator.next();
System.out.println(next);
- int size()
- boolean retainAll(Collection c) (获取交集元素,放在A中,返回值表示A是否发生变化,如果没有取到交集元素A集合会被清空)
- Object[] toArray() (集合转换为数组)
List:
List集合:元素有序(存取顺序一致),且允许元素重复
特有方法:
- void add(int index,E element)
- E remove(int index) (移除指定索引处的元素,返回移除的元素)
- E get(int index)
- E set(int index,E element)(更改指定索引处的元素,返回被替元素)
- int indexOf(Object o)(返回指定元素首次出现位置的索引,无返-1)
- int lastIndexOf(Object o)(返回指定元素最后出现位置的索引,无返-1)
- void sort(Comparator<? super E> c) 排序。举例:
list.sort(new Comparator() {
@Override
public int compare(Object a, Object b) {
System.out.println(a + "====" + b);
Integer num1 = (Integer) a;
Integer num2 = (Integer) b;
//正 负 0
return num2 - num1;
}
});
结果:
00====100
10====100
20====10
20====100
20====10
1====20
1====10
50====20
50====100
[100, 100, 50, 20, 10, 1]
迭代器:ListIterator (父接口迭代器的子接口):
特有功能:
- boolean hasPrevious(): 是否存在前一个元素
- E previous(): 返回列表中的前一个元素
这两个方法可用于反向迭代。
迭代List有三种方式:
//使用父类迭代器
Iterator iterator = list.iterator();
while (iterator.hasNext()) {
Object next = iterator.next();
System.out.println(next);
}
//使用自己的迭代器
ListIterator listIterator = list.listIterator();
while (listIterator.hasNext()) {
Object next = listIterator.next();
System.out.println(next);
}
//JDK1.8 增加的迭方法
list.forEach(new Consumer() {
@Override
public void accept(Object o) {
System.out.println(o);
}
});
注意:反向遍历要先正向遍历
while (listIterator.hasPrevious()) {
Object previous = listIterator.previous();
System.out.println(previous);
}
注意:
迭代器操作集合时,如果有增删操作(使用集合的add),会引起并发修改异常。
解决:
- 使用listIterator.add();
- for循环
ArrayList
沿用父类方法,底层数组,查询快,增删慢,线程不安全,效率高。
Vector
底层数据结构是数组,查询快,增删慢。线程安全,效率低。
特有方法:
- public void addElement(E obj) (添加)
- public E elementAt(int index)(获取指定索引处的元素)
- public Enumeration elements()(迭代器)
Enumeration elements = vector.elements();
while (elements.hasMoreElements()) {
Object o = elements.nextElement();
System.out.println(o);
}
LinkedList
底层数据结构是链表,查询慢,增删快。线程不安全,效率高。
特有方法:
- public void addFirst(E e)及addLast(E e) (加开头和末尾)
- public E getFirst()及getLast()
- public E removeFirst()及public E removeLast()
- pop() (从堆栈处弹出一个元素)
- poll() (弹出第一个元素)
泛型:
(1)把数据类型明确工作,推迟到创建对象或者调用方法时才去明确的一种机制,只能是引用类型
(2)可以定义在接口,类,方法上
(3)语法: <K,V>
- public class 类名<泛型类型1,…>
- public <泛型类型> 返回类型 方法名(泛型类型 变量名)
- public interface 接口名<泛型类型>
- 泛型通配符<?>
- ? extends E: 向下限定,E及其子类
- ? super E: 向上限定,E及其父类
新语法:
(1)增强for
- for(元素数据类型 变量 : 数组或者Collection集合) {
使用变量即可,该变量就是元素
}
注意:迭代集合的时候不能增删元素
(2)可变参数:
- 语法:修饰符 返回值类型 方法名(数据类型… 变量名){}
(3)asList(将数组转换为集合)
- public static List < T > asList(T…a){
return new ArrayList<>(a);
}
public static void main(String[] args) {
int[] arr = {20, 30, 10};
int[] arr2 = {200, 300, 1000};
int[] arr3 = {2000, 302222, 10000};
//如你传入的是基本数据类型的数组,那转换的时候,会把数组放到集合中
List<int[]> list = Arrays.asList(arr, arr2, arr3);
for (int i = 0; i < list.size(); i++) {
int[] ints = list.get(i);
for (int i1 = 0; i1 < ints.length; i1++) {
System.out.println(ints[i1]);
}
}
System.out.println("======================================");
Integer[] nums = {20, 20, 30};
//如果那你一个引用类型的数组,会把数组中的元素取出来,放到集合中
List<Integer> integers = Arrays.asList(nums);
for (Integer integer : integers) {
System.out.println(integer);
}
Integer[] nums1 = {20, 20, 30};
Integer[] nums2 = {20, 20, 30};
Integer[] nums3 = {20, 20, 30};
//如果传入的是多个数组,会把数组放到集合中
List<Integer[]> integers1 = Arrays.asList(nums1, nums2, nums3);
for (Integer[] integers2 : integers1) {
for (Integer integer : integers2) {
System.out.println(integer);
}
}
set
元素唯一,无序,不允许重复。
HashSet
底层数据结构是哈希表,可以放null。当桶中元素较多,转为红黑树。
重写hashCode()和equals(),来保证唯一性
方法:add()
哈希表:
LinkedHashSet
有序,唯一。链表+哈希表
TreeSet
唯一,可以对元素排序。底层二叉树。
- 自然排序:空参,类要实现Comparable 接口,重写 compareTo
- 比较器排序:传入Comparator并重写compare方法 例如:
TreeSet<Student> treeSet=new TreeSet<>(new Comparator<Student>){
@Override
public int compare(Student s1,Student s2){
int num=s1.getName().length()-s2.getName().length();
return -num
}
}
Map
接口,存储键值映射的数据。
只跟键有关,键采用哈希表存储。
键相同,值覆盖。put()方法返回的是旧值。
HashMap 并允许使用 null 值和 null 键 线程不安全,效率高
Hashtable 不允许null 值和null 键 线程安全,效率低
HashMap:
哈希表。无序,可重复。
方法:
- 添加:
- put(K key,V value)(如果键是第一次存储,就直接存储元素,返回null
如果键不是第一次存在,就用值把以前的值替换掉,返回以前的值) - 删除:
- void clear():移除所有的键值对元素
- V remove(Object key):根据键删除键值对元素,并把值返回
- boolean containsKey(Object key):判断集合是否包含指定的键
- boolean containsValue(Object value):判断集合是否包含指定的值
- boolean isEmpty():判断集合是否为空
- 获取:
- Set<Map.Entry<K,V>> entrySet(): 返回一个键值对的Set集合(拿到Map.Entry<K,V>型的对象后,调用getkey()和getvalue())
- V get(Object key):根据键获取值
- Set keySet():获取集合中所有键的集合
- Collection values():获取集合中所有值的集合
- int size():返回集合中的键值对的对数
遍历:(三种方式)
public static void main(String[] args) {
HashMap<String, String> hashMap = new HashMap<>();
hashMap.put("文章", "马伊琍");
hashMap.put("王宝强", "蓉儿");
hashMap.put("贾乃亮", "李小璐");
hashMap.put("陈羽凡", "白百合");
hashMap.put("陈思成", "佟丽亚");
hashMap.put("大郎", "金莲");
//String val = hashMap.get("文章");
//System.out.println(val);
//遍历Map集合的方式
// 方式1:采用 键找值
//获取所有键的集合
Set<String> keySet = hashMap.keySet();
for (String key : keySet) {
String value = hashMap.get(key);
System.out.println(key + "=====" + value);
}
System.out.println("=========================");
//方式2:把所有的键值对,对象 Node,对象获取出来。
Set<Map.Entry<String, String>> entries = hashMap.entrySet();
//System.out.println(entries);
for (Map.Entry<String, String> entry : entries) {
//System.out.println(entry);
String key = entry.getKey();
String value = entry.getValue();
System.out.println(key + "===" + value);
}
System.out.println("===============================");
//方式3:
hashMap.forEach(new BiConsumer<String, String>() {
@Override
public void accept(String key, String value) {
System.out.println(key + "====" + value);
}
});
}
LinkedHashMap:
链表和哈希表 元素有序 并且唯一。
TreeMap
不允许插入null。
类似于TreeSet,自然排序和选择排序,只跟键有关。
另:集合嵌套。