1 数据结构
1.1 什么是数据结构
- 数据结构是存在一种或者多种关系数据元素的集合。带有”结构”的数据元素的集合“,结构就是数据之间的关系
1.2 数据结构的分类
- 数据结构按照按照简单的逻辑分类分为线性结构和非线性结构。
- 线性数据结构:数据的各个节点是线性关系,有且仅有一个开始端点和结束端点(栈、队列、数组)
- 非线性数据结构:数据的各个节点有一种或者多种非线性关系,一个节点存在一种或者多种直接前趋节点和直接后继节点。(表结构、树结构、图结构等)
1.3 常见的数据结构
- 栈结构,是一种特殊线性结构,是一种限制表的一端插入和删除的线性表,插入和删除的一端是栈顶,另外一端为栈底。先进后出。
- 队列结构,限制表的一端数据的插入,另外一端数据的删除,删除的一端称为表头,插入的一端为表尾先进先出。
- 数组结构,是储存相同数据类型若干数据元素的有序的数据元素集合根据索引操作。
- 链表结构,按照链式存储方式的数据结构,在屋里面空间表现在非连续的特点,每个结点都包含的数据域和指针域,指针域持有了下一个元素的地址,(单向链表、双向链表、循环链表)
1.4 散列表(hashtable)
1.4.1 什么是散列表
- 散列表又叫hash表,是根据关键码值(key value)直接访问的数据结构,实际上就是把关键码值映射在表中进行访问的数据结构,例如:给定表M,存在某种映射函数f(key),把关键字key 带入到函数中就能得到value的地址,表就称为哈希表,f(key)函数就称为哈希函数。
- 哈希函数有利于快速的插入和删除,有利快速的定位元素
1.4.2 链式哈希表
- 由一组链表组成,每个链表称为桶,按照散列的方式把表存入桶中
- 插入数据时,把key带入哈希函数中,函数会返回数据属于那个桶,然后存入到相应的列表中。
- 查询一个数据中,按照相同的方法计算出元素数据具体的列表,然后遍历列表,知道得到相应的元素
- 哈希扩容:当链表不够时要进行扩容,扩容后所有的元素都要被重新hash
- 哈希碰撞:两个不同的值(比如小王、小曾的学号)经过hash计算后,得到的hash值相同,后来的李四要放到原来的张三的位置,但是数组的位置已经被张三占了,导致冲突。
2 集合框架概要
2.1 什么集合框架
- 集合框架是用来储存对象,分为list、set、map
2.2 集合框架的分类
- List 是有序的、可重复的一般分为arrayList、vetcor、LinkedList;
- Set 是无序的,不可以重复的一般分为hashset、Treeset 、LinkedHashset
- Map 是存储键值对的集合实现类为HashMap、TreeMap
3 List
3.1 什么List 数据结构
- List是Collection下的一个线性接口,能够精准的控制数据插入的位置,能够通过索引访问数据,索引的第一个下标是0,储存的是有序、可以重复的对象
3.2 List的常见实现类
- ArrayList 是动态的数组,又不同于普通Java数组,它是可以自动增长,不能存储基本数据类型,只能存储对象,删除和插入慢,查询快。
- LinkedList 是链表的数据结构,有着非连续的特点,插入和删除速度快,查询速度慢。
3.3 List的常用方法
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
public class Test3 {
public static void main(String[] args) {
//声明一个list
List<String> list=new ArrayList<>();
//添加元素
list.add("小赵");
list.add("小钱");
list.add("小孙");
list.add("小李");
list.add("小曾");
System.out.println(list);
System.out.println("====================");
//删除元素
list.remove("1");
list.remove("小赵");
System.out.println(list);
System.out.println("====================");
//查询
String s = list.get(1);
System.out.println("查询的元素是"+s);
System.out.println("====================");
//修改元素
list.set(0,"大哥");
System.out.println(list);
System.out.println("====================");
//返回数组的个数
int num=list.size();
System.out.println(num);
System.out.println("====================");
//清空数组
list.clear();
//判断数组的元素是否为空
boolean bool= list.isEmpty();
System.out.println(bool);
//linkedList特有的方法
//声明一个list
LinkedList<String> Linkedlist=new LinkedList<>();
//添加元素
Linkedlist.add("第一个小赵");
Linkedlist.add("第二个小钱");
String first = Linkedlist.getFirst();
String last = Linkedlist.getLast();
System.out.println(first);
System.out.println(last);
}
}
输出
3.4 ArrayList和LinkedList区别
- ArrayList和LinkedList 都是非线程安全的,有序的
- LinkedList是链表的数据结构,ArrayList是动态的数据结构
- ArrayList的查询快于LinkedList;
- LinkedList插入和删除快于ArrayList;
4 Map
4.1什么是Map数据结构
- 底层是一个数组,每个元素都是链表,数组和链表的结合体
- 举例:给定数组table,数据元素是entry,每个entry都是键值对,每个entry都持有下一个entry的引用,table中的每个entry元素都是entry链表的首结点,同时持有下一个元素的引用。
4.2 Map的实现类
- HashMap是一个散列桶(链表+数组),储存的是关键码值的映射。基于hash的原理实现,使用put(key,value)储存对象到hashmap中,使用get(key)方式获取对象,当使用put方法传递key和value时 key会调用hashcode方法计算并返回hashcode,通过hashcode知道数据属于那个桶,并在链表中存储,是非安全线程,储存非常的快。
- Treemap,在数据的储存过程中,会对数据自动的排序,实现了sotredmap接口,是一个有序的集合
4.3 Map的常用方法
import java.util.*;
public class Test8 {
public static void main(String[] args) {
//定益一个map
HashMap hashMap=new HashMap();
//增加元素
hashMap.put("1","赵");
hashMap.put("2","王");
hashMap.put("3","杨");
hashMap.put("4","苟");
hashMap.put("5","曾");
hashMap.put("6","李");
hashMap.put("7","刘");
System.out.println(hashMap);
System.out.println("=========================");
//删除元素
hashMap.remove("7");
System.out.println(hashMap);
System.out.println("=========================");
//判断map是否有键1
boolean bool=hashMap.containsKey("1");
System.out.println(bool);
System.out.println("=========================");
//判断map是否有值曾
boolean bool1=hashMap.containsValue("曾");
System.out.println(bool1);
System.out.println("=========================");
//获取所有键的集合
Set set = hashMap.keySet();
System.out.println(set);
System.out.println("=========================");
//获取所有值的集合
Collection values = hashMap.values();
System.out.println(values);
System.out.println("=========================");
//获取map是否为空、长度、单个数组的值
boolean boo12=hashMap.isEmpty();
System.out.println(boo12);
int size = hashMap.size();
System.out.println(size);
String o = (String)hashMap.get("5");
System.out.println(o);
System.out.println("=========================");
//enyset方法返回的是一个set集合,set的元素是Map.entry<k,v>,entry是entry
//的内部接口,拥有getvalue,getkeys,equal等方法
Set<Map.Entry<String,String>> set1 = hashMap.entrySet();
Iterator iterator=set1.iterator();
while (iterator.hasNext()){
Map.Entry<String,String> next = (Map.Entry<String,String>)iterator.next();
String key = next.getKey();
String value = next.getValue();
System.out.println("key:"+key+" "+"value:"+value);
}
}
}
4.4 HashMap和TreeMap使用的选择
- hashmap是无序的,可是实现对元素的快速的检索、删除、和插入;
- treemap的可以对元素进行排序,但是性能稍差。
- jdk1.7 hashmap以前是数组+链表,Jdk1.8以后是数组+链表+红黑树
5 Set
5.1 什么是Set
- set相对list是简单的数据集合,不能保存重复的元素,存储的是无序、唯一的元素。
- set不能保存重复的元素,实例原理可以参考map,因为set的实现类对应map的一种封装,hashset对应hashmap的封装,treeset对应treemap
- hashset的底层是hashmap,当使用put方法存储对象时,新加入的entry的key和原有集合的key相同时,新加入的vlaue会覆盖原有参数的value;
- hashmap可以存储最多一个null值,treeset不能存储null元素;
5.2 Set的实现类
- hashMap是基于hash的原理实现的,存储和检索的速度快,是无序的
- treeset储存对象时候能对元素进行排序,treeset是sotredset接口唯一的实现类
5.3 set的常用方法
import java.util.HashSet;
import java.util.TreeSet;
public class Test9 {
public static void main(String[] args) {
//建立一个hashset集合
HashSet<Integer> hashSet=new HashSet<>();
//增加元素
hashSet.add(5);
hashSet.add(3);
hashSet.add(6);
hashSet.add(8);
hashSet.add(9);
hashSet.add(52);
hashSet.add(52);
System.out.println(hashSet);
System.out.println("不能打印重复元素");
System.out.println("==================");
//移除元素
hashSet.remove(9);
System.out.println(hashSet);
System.out.println("==================");
//判断集合里面是否有元素3
boolean contains = hashSet.contains(52);
System.out.println(contains);
System.out.println("==================");
//集合的大小
int size = hashSet.size();
System.out.println(size);
System.out.println("==================");
//清空元素
hashSet.clear();
System.out.println(hashSet);
System.out.println("==================");
//建立treeset集合
TreeSet<Integer> treeSet=new TreeSet<>();
//增加元素
treeSet.add(5);
treeSet.add(3);
treeSet.add(6);
treeSet.add(8);
treeSet.add(9);
treeSet.add(52);
treeSet.add(52);
//打印排序集合
System.out.println(treeSet);
}
}
5.4 HashSet和TreeSet的区别
- HashSet是无序的,存储和检索快,TreeSet进行排序;
- HashSet的数据结构hash表,TreeSet的数据结构是红黑树;
- 插入和删除使用HashSet,排序的时候使用TreeSet;