集合大纲
基础知识
Collection
Map
数据结构
数据物理结构
数组
静态数组
动态数组插入与删除
链表
单向链表
双向链表
插入与删除效率高
索引
散列
把对象部分元素值通过某种算法得到一个地址值,存入对应地址,方便通过对象获取地址
数据逻辑结构
锁和阻塞
悲观锁:
无论多线程出现并发问题的概率多大,都加锁
synchronized:
在方法上加上此关键字即可,方法变成串行
多线程访问时,排成队列,其中一个线程拿到锁,执行完后释放锁
加锁和释放锁自动进行
执行过程中可以睡眠,wait,释放锁,让其他线程执行notify(随机)
ReentrantLock:
需要创建对象
ReentrantLock lock=new ReentrantLock;
Condition condition=lock.newCondition();
加锁和释放锁需要手动进行
lock.lock();//加锁,无返回值
lock.tryLock();//加锁成功返回true
阻塞和唤醒(不是随机的):condition.await condition.signal
lock.unLock();//释放锁
乐观锁:无锁机制
当出现并发问题时才加锁
cas+自旋:
cas:compare and set 比较然后设置
Unsafe类,用于调操作系统的指令,来保证cas的原子性
例如:
int i=0;
利用compare 判断如果i=0,则set设置i=1,否则无法设置成功,因此只有一个线程cas能执行成功
cas+自旋的锁机制:实现串行
for(; ; ){
cas:失败 continue
成功 往下执行
Thread记录线程
阻塞和唤醒:LockSupport.park() LockSupport.unPark(指定线程)
}
List之ArrayList
数据结构:动态数组
package com.mingmao.set.arraylist;
import java.util.ArrayList;
public class Test {
public static void main(String[] args) {
//集合 存放元素的容器 可以实现元素的增删改查
//元素可重复 有序
// 无约束
ArrayList list1=new ArrayList();
list1.add(123);
list1.add("abc");
//约束元素的数据类型<数据类型>,此处只能是引用类型
ArrayList<String> list2=new ArrayList<>();
//增
list2.add("abc");
list2.add("aaa");
list2.add("bbb");
list2.add(3,"ddd");
//删
list2.remove(1);
list2.remove("ddd");
//改
list2.set(1,"ccc");
//查
System.out.println(list2.get(1));
//打印
System.out.println(list1);
System.out.println(list2);
//获取集合的长度尺寸,元素的个数
int size=list2.size();
System.out.println(size);
//遍历集合
for (int i = 0; i < list2.size(); i++) {
System.out.println(list2.get(i));
}
}
}
练习-学生管理系统
package com.mingmao.set.arraylist;
import java.util.ArrayList;
import java.util.Scanner;
public class Student {
//属性
private String studentid;
private String name;
private String age;
private String hometown;
//构造器
public Student() {
}
//get set方法
public String getStudentid() {
return studentid;
}
public void setStudentid(String studentid) {
this.studentid = studentid;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
}
public String getHometown() {
return hometown;
}
public void setHometown(String hometown) {
this.hometown = hometown;
}
//学生管理系统入口方法
public void entrance(){
ArrayList<String[]> studentList=new ArrayList<>();
String[] student={"学号","姓名","年龄","居住地"};
studentList.add(student);
Scanner scanner=new Scanner(System.in);
StudentManagement studentManagement=new StudentManagement();
layer1: do{
System.out.println("------------------欢迎来到学生管理系统------------------");
System.out.println("1.添加学生");
System.out.println("2.删除学生");
System.out.println("3.修改学生");
System.out.println("4.查看所有学生");
System.out.println("5.退出");
System.out.println("请输入你的选择:");
int num=scanner.nextInt();
switch (num){
case 1:
studentManagement.add(studentList);
break;
case 2:
studentManagement.delete(studentList);
break;
case 3:
studentManagement.modify(studentList);
break;
case 4:
studentManagement.get(studentList);
break;
case 5:
System.out.println("谢谢使用!");
break layer1;
default:
break;
}
}while (true);
}
public static void main(String[] args) {
Student student=new Student();
student.entrance();
}
}
package com.mingmao.set.arraylist;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Scanner;
public class StudentManagement {
public void add(ArrayList<String[]> studentList){
Student student=new Student();
Scanner scanner=new Scanner(System.in);
System.out.println("请输入学生学号:");
student.setStudentid(scanner.nextLine());
System.out.println("请输入学生姓名:");
student.setName(scanner.nextLine());
System.out.println("请输入学生年龄:");
student.setAge(scanner.nextLine());
System.out.println("请输入学生居住地:");
student.setHometown(scanner.nextLine());
String[] studentInformation={student.getStudentid(),student.getName(),student.getAge(),student.getHometown()};
studentList.add(studentInformation);
System.out.println("添加学生成功");
}
public void delete(ArrayList<String[]> studentList){
Student student1=new Student();
Scanner scanner=new Scanner(System.in);
System.out.println("请输入你要删除的学生的学号:");
student1.setStudentid(scanner.nextLine());
studentList.remove(getIndex(studentList,student1.getStudentid()));
System.out.println("删除学生成功");
}
public void modify(ArrayList<String[]> studentList){
Student student1=new Student();
Scanner scanner=new Scanner(System.in);
System.out.println("请输入你要修改的学生的学号:");
student1.setStudentid(scanner.nextLine());
System.out.println("请输入学生新姓名:");
student1.setName(scanner.nextLine());
System.out.println("请输入学生新年龄:");
student1.setAge(scanner.nextLine());
System.out.println("请输入学生新居住地:");
student1.setHometown(scanner.nextLine());
String studentInformation[]={student1.getStudentid(),student1.getName(),student1.getAge(),student1.getHometown()};
studentList.set(getIndex(studentList,student1.getStudentid()),studentInformation);
System.out.println("修改学生成功");
}
public void get(ArrayList<String[]> studentList){
for (int i = 0; i < studentList.size(); i++) {
for (int i1 = 0; i1 < 4; i1++) {
System.out.print(studentList.get(i)[i1]+"\t");
}
System.out.println();
}
}
public int getIndex(ArrayList<String[]> studentList,String studentid){
int index=0;
for (int i = 0; i < studentList.size(); i++) {
if(studentList.get(i)[0].equals(studentid)){
index=i;
}
}
return index;
}
}
List之CopyOnWriteArrayList
复制新数组,写操作新数组,读旧数组,读写分离。写操作加锁。
问题,读的不一定是最新数据。
解决了并发问题,应用于对读的实时性不高的场景。
List之LinkedList
数据结构:双向链表
package com.mingmao.set.linkedlist;
import java.util.LinkedList;
public class Test {
public static void main(String[] args) {
//创建 可以指定泛型也可以不指定
LinkedList list1=new LinkedList();
LinkedList<Integer> list2=new LinkedList<>();
//增
list2.add(123);
list2.add(234);
list2.add(9999);
System.out.println(list2);
list2.addFirst(333);
System.out.println(list2);
list2.addLast(666);
System.out.println(list2);
//删
list2.remove(3);
System.out.println(list2);
//改
list2.set(2,8787);
System.out.println(list2);
//查
System.out.println(list2.get(3));
System.out.println(list2.getFirst());
System.out.println(list2.getLast());
}
}
LinkedList与ArrayList的比较
循环的往集合中插入元素
package com.mingmao.set.linkedlist;
import java.util.ArrayList;
import java.util.LinkedList;
public class Test1 {
public static void main(String[] args) {
ArrayList al=new ArrayList();
LinkedList ll=new LinkedList();
long d1=System.currentTimeMillis();
for (int i = 0; i < 100000; i++) {
al.add(0,i);
}
System.out.println(al);
long d2=System.currentTimeMillis();
for (int i = 0; i < 100000; i++) {
ll.addFirst(i);
}
System.out.println(ll);
long d3=System.currentTimeMillis();
System.out.println("ArrayList执行时间:"+(d2-d1));
System.out.println("LinkedList执行时间:"+(d3-d2));
/*
ArrayList执行时间:604
LinkedList执行时间:20
*/
// LinkedList的插入执行效率要高出很多
}
}
Set
HashSet
package com.mingmao.set.set.hashset;
import java.util.HashSet;
import java.util.Set;
public class Test {
public static void main(String[] args) {
Set<String> hashSet=new HashSet<>();
hashSet.add("Java");
hashSet.add("Go");
hashSet.add("Rust");
hashSet.add("Java");
System.out.println(hashSet);//[Java, Rust, Go] 自动去掉重复元素,存取无序,无索引
for (String s : hashSet) {
System.out.println("集合元素值:"+s+" "+"集合元素的哈希值:"+s.hashCode());
}
/*
集合元素值:Java 集合元素的哈希值:2301506
集合元素值:Rust 集合元素的哈希值:2558980
集合元素值:Go 集合元素的哈希值:2312
*/
//equals 没有重写,默认比较地址,两个对象相同但地址不同,有重复元素
Set<CellPhone> cellPhoneHashSet=new HashSet<>();
cellPhoneHashSet.add(new CellPhone("iphone",5999));
cellPhoneHashSet.add(new CellPhone("sanxing",2999));
cellPhoneHashSet.add(new CellPhone("xiaomi",1999));
cellPhoneHashSet.add(new CellPhone("iphone",5999));
System.out.println(cellPhoneHashSet.size());//4
System.out.println(cellPhoneHashSet);
//[com.mingmao.set.set.hashset.CellPhone@74a14482, com.mingmao.set.set.hashset.CellPhone@4554617c, com.mingmao.set.set.hashset.CellPhone@1b6d3586, com.mingmao.set.set.hashset.CellPhone@1540e19d]
//重写equals和hashCode后,比较值,两个对象相同,无重复元素
Set<CellPhone> cellPhoneHashSet2=new HashSet<>();
cellPhoneHashSet2.add(new CellPhone("iphone",5999));
cellPhoneHashSet2.add(new CellPhone("sanxing",2999));
cellPhoneHashSet2.add(new CellPhone("xiaomi",1999));
cellPhoneHashSet2.add(new CellPhone("iphone",5999));
System.out.println(cellPhoneHashSet2.size());//3
System.out.println(cellPhoneHashSet2);
//[com.mingmao.set.set.hashset.CellPhone@777ad92b, com.mingmao.set.set.hashset.CellPhone@84a3ae35, com.mingmao.set.set.hashset.CellPhone@77e5286e]
}
}
package com.mingmao.set.set.hashset;
import java.util.Objects;
public class CellPhone {
private String name;
private int price;
public CellPhone() {
}
public CellPhone(String name, int price) {
this.name = name;
this.price = price;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getPrice() {
return price;
}
public void setPrice(int price) {
this.price = price;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
CellPhone cellPhone = (CellPhone) o;
return price == cellPhone.price &&
Objects.equals(name, cellPhone.name);
}
@Override
public int hashCode() {
return Objects.hash(name, price);
}
}
LinkedHashSet
package com.mingmao.set.set.linkedhashset;
import java.util.LinkedHashSet;
import java.util.Set;
public class Test {
public static void main(String[] args) {
//特有属性 有序
Set<String> linkedHashSet=new LinkedHashSet<>();
linkedHashSet.add("Java");
linkedHashSet.add("Go");
linkedHashSet.add("Rust");
linkedHashSet.add("Java");
System.out.println(linkedHashSet.size());//3
System.out.println(linkedHashSet);//[Java, Go, Rust]
}
}
TreeSet
package com.mingmao.set.set.treeset;
import java.util.Comparator;
import java.util.Set;
import java.util.TreeSet;
public class Test {
public static void main(String[] args) {
//字符串默认排序:字典顺序升序
Set<String> treeSet=new TreeSet<>();
treeSet.add("Java");
treeSet.add("Go");
treeSet.add("Rust");
treeSet.add("Java");
System.out.println(treeSet.size());//3
System.out.println(treeSet);//[Go, Java, Rust] 字符串的字典顺序
//字符串按照字典顺序降序输出
Set<String> treeSet1=new TreeSet<>(new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
return o2.compareTo(o1);
}
});
treeSet1.add("Java");
treeSet1.add("Go");
treeSet1.add("Rust");
treeSet1.add("Java");
System.out.println(treeSet1.size());//3
System.out.println(treeSet1);//[Rust, Java, Go]
}
}
Map
HashMap
JDK7:
Key值不能重复
package com.mingmao.set.map.hashmap;
import java.util.HashMap;
public class Test {
public static void main(String[] args) {
HashMap<Integer, Student> hashMap=new HashMap<>();
//增
hashMap.put(001,new Student("001","小红","13124567865"));
hashMap.put(002,new Student("002","小明","13824567865"));
hashMap.put(003,new Student("003","小李","13524567865"));
System.out.println(hashMap.size());//3
//查
Student s=hashMap.get(001);
System.out.println(s);//Student{id='001', name='小红', tel='13124567865'}
System.out.println(hashMap.get(002));//Student{id='002', name='小明', tel='13824567865'}
}
}
package com.mingmao.set.map.hashmap;
public class Student {
private String id;
private String name;
private String tel;
public Student() {
}
public Student(String id, String name, String tel) {
this.id = id;
this.name = name;
this.tel = tel;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getTel() {
return tel;
}
public void setTel(String tel) {
this.tel = tel;
}
@Override
public String toString() {
return "Student{" +
"id='" + id + '\'' +
", name='" + name + '\'' +
", tel='" + tel + '\'' +
'}';
}
}
TreeMap
有序
package com.mingmao.set.map.treemap;
import sun.reflect.generics.tree.Tree;
import java.util.Comparator;
import java.util.TreeMap;
import java.util.function.BiConsumer;
public class Test {
public static void main(String[] args) {
//自然排序
TreeMap<String,Integer> treeMap=new TreeMap<>();
treeMap.put("hello",12345);
treeMap.put("aorld",5678);
treeMap.put("wait",567);
treeMap.forEach(new BiConsumer<String, Integer>() {
@Override
public void accept(String s, Integer integer) {
System.out.println("键:"+s+"值:"+integer);
}
});
/*
按照键的字典顺序升序排列:
键:aorld值:5678
键:hello值:12345
键:wait值:567
*/
//定制排序
TreeMap<Student,Integer> treeMap1=new TreeMap<>(new Comparator<Student>() {
@Override
public int compare(Student o1, Student o2) {
return o2.getId().compareTo(o1.getId());
}
});
treeMap1.put(new Student("001","小红","13178965430"),789);
treeMap1.put(new Student("002","小名","13278965430"),123);
treeMap1.put(new Student("003","小李","13578965430"),55789);
treeMap1.forEach(new BiConsumer<Student, Integer>() {
@Override
public void accept(Student student, Integer integer) {
System.out.println("键:"+student+"值:"+integer);
}
});
/*
键:Student{id='003', name='小李', tel='13578965430'}值:55789
键:Student{id='002', name='小名', tel='13278965430'}值:123
键:Student{id='001', name='小红', tel='13178965430'}值:789
*/
}
}
package com.mingmao.set.map.treemap;
public class Student {
private String id;
private String name;
private String tel;
public Student() {
}
public Student(String id, String name, String tel) {
this.id = id;
this.name = name;
this.tel = tel;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getTel() {
return tel;
}
public void setTel(String tel) {
this.tel = tel;
}
@Override
public String toString() {
return "Student{" +
"id='" + id + '\'' +
", name='" + name + '\'' +
", tel='" + tel + '\'' +
'}';
}
}
Collections
package com.mingmao.set.collections;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
public class Test {
public static void main(String[] args) {
//Collections工具类方法
//以ArrayList为例
ArrayList<String> list=new ArrayList<>();
//添加多个元素
Collections.addAll(list,"abc","ghh","ljk");
System.out.println(list);//[abc, ghh, ljk]
//打乱集合顺序
Collections.shuffle(list);
System.out.println(list);//[ljk, ghh, abc]每次运行结果不同
//将集合中的元素按照默认规则排序
Collections.addAll(list,"adf","bfh","jkl");
System.out.println(list);//[ljk, ghh, abc, adf, bfh, jkl]
Collections.sort(list);
System.out.println(list);//[abc, adf, bfh, ghh, jkl, ljk]
//定制排序--在类中继承Comparable排序
ArrayList<Student> list1=new ArrayList<>();
Collections.addAll(list1,new Student("002","小红","13156784328"),new Student("001","小明","13245678765"),new Student("003","小亮","13546789876"));
System.out.println(list1);
//[Student{id='002', name='小红', tel='13156784328'}, Student{id='001', name='小明', tel='13245678765'}, Student{id='003', name='小亮', tel='13546789876'}]
Collections.sort(list1);
System.out.println(list1);
//[Student{id='001', name='小明', tel='13245678765'}, Student{id='002', name='小红', tel='13156784328'}, Student{id='003', name='小亮', tel='13546789876'}]
//定制排序--在调用sort时定制排序
System.out.println(list1);
//[Student{id='001', name='小明', tel='13245678765'}, Student{id='002', name='小红', tel='13156784328'}, Student{id='003', name='小亮', tel='13546789876'}]
Collections.sort(list1, new Comparator<Student>() {
@Override
public int compare(Student o1, Student o2) {
return o2.getName().compareTo(o1.getName());
}
});
System.out.println(list1);
//[Student{id='002', name='小红', tel='13156784328'}, Student{id='001', name='小明', tel='13245678765'}, Student{id='003', name='小亮', tel='13546789876'}]
}
}
package com.mingmao.set.collections;
public class Student implements Comparable<Student>{
private String id;
private String name;
private String tel;
public Student() {
}
public Student(String id, String name, String tel) {
this.id = id;
this.name = name;
this.tel = tel;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getTel() {
return tel;
}
public void setTel(String tel) {
this.tel = tel;
}
@Override
public String toString() {
return "Student{" +
"id='" + id + '\'' +
", name='" + name + '\'' +
", tel='" + tel + '\'' +
'}';
}
@Override
public int compareTo(Student o) {
return this.getId().compareTo(o.getId());
}
}