线性数据结构:数组,栈,队列,链表
非线性结构:树,哈希表
集合中存储的元素都是引用类型,每个元素都有对应的哈希值(hashCode),
元素对象的hashCode值决定了在哈希表中的存储位置
当往集合中添加元素对象时,先判断该对象和集合中的对象hashCode是否相等
相等:再继续判断新对象和集合对象equals比较
不相等:直接把新对象存储到hashCode指定的位置上
流程图
为什么存储到表中的对象都要重写hashCode和equals方法?
对于自定义类,我们需要重写这两种方法,在进行对比的时候,
我们首先使用hashCode()进行对比,如果hashCode值一样,
但是其业务对象内容不一定一样,所以我们需要再进行 equals()比较,
两者一样则代表两个对象真的相同,
反之hashCode都不一样的对象(equals也肯定是不一样),
这样就能很大程度的提高了效率
当向树中添加元素时,如果树中没有元素,直接添加作为根(root)
平衡二叉树:一个节点的左子树的层数和右子树的层数相差不能超过1
集合有三种迭代方式
import java.util.ArrayList;
import java.util.Iterator;
public class Test01 {
public static void main(String[] args) {
ArrayList<String> arrayList = new ArrayList<>();
arrayList.add("小月");
arrayList.add("小轩");
arrayList.add("小罗");
}
}
}
//1.普通for
for (int i = 0; i <arrayList.size() ; i++) {
String item = arrayList.get(i);
System.out.print(item+" ");
foreach遍历.是一种语法糖
//2.只要集合实现类实现了Iterable接口,该集合就支持foreach
/*
* String 迭代类型
* item 迭代变量
* list 迭代的目标集合
*
* */
for (String item:arrayList) {
System.out.print(item +" ");
}
System.out.println();
Iterator表示迭代器对象,迭代器中拥有一个指针,默认指向第一个元素之前
boolean hasNext()
:判断指针是否存在下一个元素Object next()
:获取指针位置下一个元素,获取后指针向后移动一位//3.迭代器
/*
*Iterable中定义了一个方法,用于返回集合的迭代器 =>
iterator() =>方法返回迭代器对象
*
* */
//arrayList.iterator()获取迭代器对象 ,
//返回一个迭代器接口Iterator
Iterator<String> it = arrayList.iterator();
while (it.hasNext()){
String item = it.next();
System.out.print(item +" ");
}
//迭代器优化
for (Iterator<String> it2 =arrayList.iterator(); it2.hasNext();){
String item = it2.next();
System.out.print(item +" ");
}
注意:并发修改异常
在迭代集合时删除元素
for (String item:arrayList) {
if(item.equals("小罗")){
arrayList.remove(item);
}
}
报错:java.utils.ConcurrentModificationException,并发修改异常
原因:不允许在迭代过程中改变集合的长度(不能添加和删除),
如果迭代过程中删除元素,就不能使用集合中的remove方法,
只能使用迭代器的remove方法
Set接口是Collection的子接口,Set定义了一种规范(该容器不记录元素的添加顺序,不允许元素重复)无序且唯一
Set接口常用的实现类有:
HashSet做等值查询效率高,TreeSet做范围查询效率高,一般使用HashSet
操作:
import java.util.HashSet;
import java.util.Iterator;
public class Test01 {
public static void main(String[] args) {
//创建HashSet集合对象
HashSet<Integer> set = new HashSet<>();
//1.添加
set.add(10);
set.add(20);
set.add(30);
//2.删除
set.remove(10);
System.out.println(set);
//移除所有元素
//set.clear();
//System.out.println(set);
//3.查
System.out.println(set.isEmpty()); //是否为空
System.out.println(set.size()); //长度
//4.迭代器遍历
Iterator<Integer> it = set.iterator();
while(it.hasNext()){
Integer item = it.next();
System.out.print(item+" ");
}
}
}
Tree类底层采用的是红黑树算法,会对存储的元素对象默认使用自然排序(从小到大)
如果我们自定义一个类,存储到TreeSet中,那么我们需要让该类实现Comparable接口
,
并覆盖compareTo方法
,编写比较规则.
TreeSet会调用元素的compareTo方法来比较元素的大小关系,然后将集合元素按照升序排列,一般来说JDK自带的类都实现了Comparable接口,例如八大包装类和String,所以一般我们进行自定义类的时候才实现java.util.Comparable
接口
比较策略:能否获取元素的源代码权限
public interface Comparable<T> {
public int compareTo(T o);
}
规则:
例子:
@Override
//按年龄排序,当前对象this 与 传入对象o比较
public int compareTo(Student o) {
/*if (this.getAge()o.getAge()){
return 1;
}else{
return 0;
}*/
return this.getAge() -o.getAge();
Map(映射),映射表示的两个集合中元素间的一种对应关系,我们使用Map来封装与表示
严格来讲,Map并不是集合,而是表示两个集合间的一种关系,Map没有实现Collection接口,但是我们还是习惯性成Map为集合
Set和List是单元素集合,Map是双元素集合,每次都需要存储两个元素(key,value)
添加
boolean put(Object key,Object value)
:存储一个键值对到Map中boolean putAll(Map m)
:把m中的所有键值对添加到当前Map中删除
Object remove(Object key)
:从Map中删除指定key,并返回被删除key对应的value修改
查询
int size()
:返回当前Map中键值对个数boolean isEmpty()
:判断当前Map中键值对是否为空Object get(Object key)
:返回Map中指定key对应的value值,如果不存在该key,返回nullboolean containsKey(Object key)
:判断Map中是否包含指定keyboolean containsValue(Object value)
:判断Map中是否包含指定valueSet keySet()
:返回Map中所有key所组成的Set集合Collection values()
:返回Map中所有value所组成的Collection集合Set entrySet()
:返回Map中所有键值对所组成的Set集合例子:
import java.util.HashMap;
import java.util.HashSet;
public class Test01 {
public static void main(String[] args) {
HashMap<String, String> map = new HashMap<>();
//添加操作
map.put("轩", "月");
map.put("轩1", "鸢");
map.put("轩2", "辕");
System.out.println(map);
//删除操作 从Map中删除指定key的键值对,并返回被删除key对应的value
map.remove("轩");
//修改,没有专门方法,通过put的key对value进行覆盖
map.put("轩1", "月月");
//查询操作
//返回Map键值对个数
System.out.println(map.size()); //2
//判断是否为空
System.out.println(map.isEmpty()); //false
//Object get(Object key):返回Map中指定key对应的value值,如果不存在该key,返回null
System.out.println(map.get("轩1"));//月月
//boolean containsKey(Object key):判断Map中是否包含指定key
System.out.println(map.containsKey("轩2"));//true
//boolean containsValue(Object value):判断Map中是否包含指定value
System.out.println(map.containsValue("月月"));//true
//Set keySet():返回Map中所有key所组成的Set集合
System.out.println(map.keySet());//[轩2, 轩1]
//Collection values():返回Map中所有value所组成的Collection集合
System.out.println(map.values());//[辕, 月月]
//Set entrySet():返回Map中所有键值对所组成的Set集合
System.out.println(map.entrySet()); //[轩2=辕, 轩1=月月]
}
}
Hash底层是使用哈希表算法,MAp中存储的key对象的hashCode决定了在哈希表中的存储位置(所以准确来讲是HashMap中的key使用了哈希表算法)
如果key是自定义对象,必须重写hashCode和equals方法,一般使用String类型作为key
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
public class Test01 {
public static void main(String[] args) {
//创建HashMap对象
HashMap<String, String> hashMap = new HashMap<>();
//添加元素
hashMap.put("轩", "月");
hashMap.put("小轩", "小月");
hashMap.put("小罗", "胖月");
hashMap.put("小猪", "月月");
//Map的迭代遍历
//调用entrySet方法,返回key的Set集合
Set<Map.Entry<String, String>> set = hashMap.entrySet();
//从而实现遍历
Iterator<Map.Entry<String, String>> iterator = set.iterator();
while (iterator.hasNext()){
Map.Entry<String,String> item = iterator.next();
System.out.print(item+" ");
}
}
}
有一个比较常用的方法
public static List asList(T... a)
:该方法可以把一个Object数组转换为List集合import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
public class Test01 {
public static void main(String[] args) {
//1.Array.asList
//把Integer[]转换为List
List<Integer> list = Arrays.asList(1, 2, 3);
System.out.println(list); //[1, 2, 3]
//把String[]转换为List
List<String> list1 = Arrays.asList("小月", "小轩", "520");
System.out.println(list1); //[小月, 小轩, 520]
ArrayList<String> arrayList = new ArrayList<>();
Collections.addAll(arrayList, "小月","小轩","小罗","520");
System.out.println(arrayList);//[小月, 小轩, 小罗, 520]
}
}
2, 3);
System.out.println(list); //[1, 2, 3]
//把String[]转换为List
List<String> list1 = Arrays.asList("小月", "小轩", "520");
System.out.println(list1); //[小月, 小轩, 520]
ArrayList<String> arrayList = new ArrayList<>();
Collections.addAll(arrayList, "小月","小轩","小罗","520");
System.out.println(arrayList);//[小月, 小轩, 小罗, 520]
}
}