##1.集合体系
* 概述:能够存储任意对象,长度可以改变.
* Collection (接口)
* |——List (接口) 有序,有索引,可重复
* |——ArrayList (类)
* |——Vector (类)
* |——LinkedList (类)
* |——Set (接口) 无序,无索引,不可重复
* |——HashSet (类)
* |——TreeSet (类)
* 集合和数组的区别
* 数组:
* 数组长度固定。
* 数组可以存储基本数据类型,也可以存储引用类型。
* 数组存储的数据类型是一致的。
* 集合:
* 集合长度可变。
* 集合只能存储引用类型。
* 集合可以存储不同类型的对象
* 总结:集合比数组强大,类似于包装类和基本类型的关系
##2.Collection接口中的成员方法
* 添加
* boolean add(Object obj) 向集合中添加一个元素(常用)
* boolean addAll(Collection c)向集合中添加一个集合的元素
* 删除
* void clear() 删除集合中所有元素
* boolean remove(Object obj) 从集合中删除指定的元素
* boolean removeAll(Collection c) 从集合中删除一个指定的集合元素
* 判断
* boolean isEmpty() 判断集合是否为空
* boolean contains(Object obj) 判断集合是否存在指定的元素
* boolean cotainsAll(Colletion c) 判断集合中是否存在指定的一个集合中的元素
* 遍历
* Iterator()
* 长度
* int size()
* 交集
* boolean retainAll(Collection c) 判断两个集合是否有相同的元素
* 把集合转数组
* Object[] toArray()
String[] arr = list.toArray(new String[list.size()]);
##3.List接口
* 1.特点
* 元素有序可重复,可以通过索引值操作对应位置的元素, 而Set中的元素是无序唯一的
* 2.成员方法(相对Collection主要是多了对索引的操作)
* 添加
* void add(int index, Object obj) 在指定位置添加元素(常用)
* 删除
* Object remove(int index) 根据指定索引删除元素,并把删除的元素返回(常用)
* 修改
* Object set(int index, Object obj) 把指定索引位置的元素修改为指定的值,返回修改前的值(常用)
* 获取
* int indexOf(Object o) 返回指定元素在集合中第一次出现的索引(常用)
* Object get(int index) 返回指定索引位置对应的元素(常用)
* ListIterator listIterator() 列表迭代器
* 截取
* List subList(int fromIndex, int toIndex) 截取集合
##4.List接口三子类
* 1.数据结构
* 栈:先进后出
* 队列:先进先出
* 数组:查询快,增删慢
* 链表:查询慢,曾删快
* 2.三子类特点
* ArrayList:底层数据结构是数组,查询快,增删慢.线程不安全,效率高.
* Vetor:底层数据结构是数组,查询快,增删慢.线程安全,效率低.
* LinkedList:底层数据结构是链表,查询慢,增删快.线程不安全,效率高
* 添加
void addFirst(Object o)
void addLast(Object o)
* 获取
Objcet getFirst()
Objcet getLast()
* 删除
Object removeFirst()
Object removeLast()
* 什么时候用? 查询多用ArrayList,增删多用LinkedList
* tips:Vetor在写法上类似Iterator,可结合记忆
##5.HashSet
* 1.哈希值概念
* 哈希值:哈希值就是调用对象的hashCode()方法后返回的一个int型数字
* 哈希桶:简单点理解就是存储相同哈希值对象的一个容器
* 2.通过重写hashCode() 和equals() 保证唯一性
* 个人理解:
* 哈希值是通过地址值计算出来的,重写equals是为了比较属性
1.重写hashCode()让相同属性哈希值相同,从而通过eqauls()判断,从而确实是否存入
2.优化hashCode是为了使不同属性的对象哈希值尽量不同,从而不走equals
* 3.线程不安全,效率高
##6.TreeSet
* 1.如何保证元素唯一性:内部采用的是二叉树结构,相同的元素就不操作
* 2.排序有两种方案
* A.对象所属的类去实现Comparable接口,重写compareTo方法.如果该方法返回0,则两个元素相同
*
public class Person implements Comparable<Person> {
@Override
public int compareTo(Object o) {
int num = this.name.compareTo(o.name);
return num == 0 ? this.age - o.age : num;
}
}
TreeSet set = new TreeSet();
set.add(new Person());
* B.调用TreeSet的带参构造方法,传入Comparator的子类对象,该子类对象重写compare(T o1, T o2)方法,如果返回0则两个元素相同
*
public class MyComparator implements Comparator {
@Override
public int compare(Object o1, Object o2) {
int num = s1.length() - s2.length();
return num == 0 ? s1.compareTo(s2) : num;
}
}
TreeSet set = new TreeSet(new MyComparator());
set.add(new Person());
##7.泛型
* A.在类上定义
* 在类上定义一个泛型
*
public class MyArrayList<T> {
}
* 在类上定义两个泛型
*
public class MyArrayList<T, S> {
}
* 在类上定义两个泛型,且第二个类型必须是第一个类型的子类
*
public class MyArrayList<T, S extends T> {
}
* 说明:
* T,S是名字,可以随意起,该处定义的泛型可以在本类的任意地方使用
* 父类上定义的泛型不能被子类继承
* B.在方法上定义
* 在方法上定义一个泛型
*
public <M> void show(M m){
}
* 在方法上定义两个泛型
*
public <M, S> void show(M m, S s){
}
* 在方法上定义两个泛型,且第二个泛型必须事第一个泛型的子类
*
public <M, S extends M> void show(M m, S s){
}
* 说明:
* T,S是名字,可以随意起,该处定义的泛型可以在该方法的任意地方使用
* C.在接口上定义泛型
* 和在类上定义一样
##8.迭代器
* 1.原理:集合的数据结构不同,所以存储方式不同,所以,取出方式也不同.这个时候,我们就把判断和获取功能定义在了一个接口中,将来,遍历哪种集合的时候,只要该集合内部实现这个接口即可。
* 迭代器是一个内部类,在集合的内部定义了一个类,这个类实现了Iterator接口
* 2.使用
*
List list = new ArrayList();
list.add(1);
list.add(3);
Iterator<Integer> iterator = list.iterator<>();
while(iterator.hasNext()){
System.out.println(iterator.next());
}
* 3.常见问题
* ConcurrentModificationException:在迭代的时候给集合增加元素,删除元素造成的
* 解决方案:通过迭代器增加删除
* 4.Iterator 和 ListIterator的区别
* 1.Iterator是ListIterator的父接口
* 2.Iterator是Collection集合的公共的取出容器中元素的方式,对于List,Set都通用.而ListIterator是List集合的特有的取出元素的方式
* 3.Iterator中只具备hasNext(),next(),remove()方法,可以删除被遍历到的元素
* 4.ListIterator中具备对遍历到的元素进行增(add)删(remove)改(set)查(next)的方法,可以对元素逆向遍历previouse相对于next,hasPreviouse相对于hasNext(用的很少)
##9.集合的遍历
* 1.集合的遍历方式
* 1.迭代
* 2.将集合转换为数组
* 3.获取集合的长度,通过get(索引)+for遍历(list集合)
* 4.使用增强for循环
* 2.for循环遍历和迭代器遍历的区别
* 1.最主要的区别就是remove方法,想要在循环的过程中删除元素就要用迭代器,因为迭代器的remove方法不仅会删除元素,还会维护一个标志,用来记录当前状态是不是可删除.而for循环角标是变化的,删除元素会报错,因为list.size()大小发生变化了
* 2.ArrayList里面维护的是数组,顺序结构,所以用get方法获取比较快,因而用for循环
LinkedList里面维护的是链表,链式结构,Iterator中的next()方法,采用的即是顺序访问的方法,因此用迭代器比较快
----------
##1.Map集合成员方法
* 增加
* V put(K key, V value) 当key在集合中不存在时,添加元素;当key在集合存在时候,替换元素
* 删除
* void clear() 清除所有键值对数据
* V remove(Object key) 根据指定的键删除键值对
* 判断
* boolean containsKey(Object key) 判断指定的键是否在集合中存在
* boolean containsValue(Object value) 判断指定的值是否在集合中存在
* boolean isEmpty 判断集合是否为空
* 获取
* Set<Map.Entry<K,V>> entrySet() 键值对对象的集合
* Object get(Object key) 根据键获取值
* Set<K> keySet() 所有键的集合
* Collection<V> values() 所有值的集合
* 长度
* int size()
##2.Map集合的两种遍历方式
* 1.遍历方式键找值(通过keySet()
*
Set<String> keySet = map.keySet();
for(String key : keySet){
System.out.println("key:"+key+" value"+map.get(key));
}
* 2.遍历方式键值对对象找键和值(通过entrySet()
*
set<Entry<String, Integer>> entrySet = map.entrySet();
for(Entry<STring, Integer> en : entrySet) {
System.Out.println(en.getKey() + "..." + en.getValue());
}
##3.HashMap
* HashTable:线程安全,效率低,不允许null键和值,HashMap是JDK1.2版本出现的
* HashMap:线程不安全,效率高,允许null键和值,Hashtable是JDK1.0版本出现的
* LinkedHashMap:底层是链表实现的可以保证怎么存就怎么取
##4.TreeMap
* 统计字符串中每个字符出现的次数
*
String str = "aaaabbbcccccccccc";
char[] arr = str.toCharArray();
HashMap<Character, Integer> hm = new HashMap<>();
for(char c : arr) {
hm.put(c, hm.containsKey(c) ? hm.get(c) + 1 : 1);
}
for (Character key : hm.keySet()) {
System.out.println(key + "=" + hm.get(key));
}
##5.Collections类
* 排序 public static void sort(List list)
* 查找 public static binarySearch(List list, Object obj)
* 反转 public static void reverse()
* 最大值 public static Object max(Collection coll)
* 随机换位 public static void shuffle(List list)
|
|