一、ArrayList集合嵌套:
举例1:
/*
* 一个班级的学生使用ArrayList<Student>
* 很多个班级:ArrayList<ArrayList<Student>>
* 创建三个班级,将三个班级的学生添加大的集合中,遍历大的集合
*/
public class Student {
private String name ;
private int age ;
public Student() {
}
public Student(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
public class ArrayListTest {
public static void main(String[] args) {
//创建一个大的集合对象
ArrayList<ArrayList<Student>> bigArray = new ArrayList<ArrayList<Student>>() ;
//第一个班级:
ArrayList<Student> array1 = new ArrayList<Student>() ;
//添加学生
Student s1 = new Student("盲僧",30) ;
Student s2 = new Student("亚索",25) ;
Student s3 = new Student("奥巴马",20) ;
array1.add(s1) ;
array1.add(s2) ;
array1.add(s3) ;
//添加到到的集合中
bigArray.add(array1) ;
//第二个班级
ArrayList<Student> array2 = new ArrayList<Student>() ;
//添加学生
Student s4 = new Student("刘备",30) ;
Student s5 = new Student("关羽",25) ;
Student s6 = new Student("张飞",20) ;
array2.add(s4) ;
array2.add(s5) ;
array2.add(s6) ;
bigArray.add(array2) ;
//第三个班级
ArrayList<Student> array3 = new ArrayList<Student>() ;
//添加学生
Student s7 = new Student("唐僧",30) ;
Student s8 = new Student("孙悟空",25) ;
Student s9 = new Student("猪八戒",20) ;
array3.add(s7) ;
array3.add(s8) ;
array3.add(s9) ;
bigArray.add(array3) ;
//遍历大的集合 ArrayList<ArrayList<Student>>
for(ArrayList<Student> array : bigArray){
for(Student s : array){
System.out.println(s.getName()+"\t"+s.getAge());
}
}
}
}
举例2:
/* TreeSet集合练习(录入5学生的姓名,语文,数学,英语:总分从高到底排序
*/
public class Student {
private String name ;
private int chinese ;//语文成绩
private int math ;//数学成绩
private int english ;//英语成绩
public Student() {
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getChinese() {
return chinese;
}
public void setChinese(int chinese) {
this.chinese = chinese;
}
public int getMath() {
return math;
}
public void setMath(int math) {
this.math = math;
}
public int getEnglish() {
return english;
}
public void setEnglish(int english) {
this.english = english;
}
//总分
public int getSum(){
return this.chinese+this.math+this.english ;
}
}
import java.util.Comparator;
import java.util.Scanner;
import java.util.TreeSet;
public class TreeSetTest {
public static void main(String[] args) {
//创建TreeSet集合对象:有参构造方式
TreeSet<Student> ts = new TreeSet<Student>(new Comparator<Student>(){
@Override
public int compare(Student s1, Student s2) {
//总分是从高到底 (主要条件)
int num = s2.getSum() - s1.getSum() ;
//次要条件
int num2 = (num==0)?s1.getChinese()-s2.getChinese():num ;
int num3 = (num2==0)?s1.getMath()-s2.getMath():num2 ;
int num4 = (num3==0)?s1.getEnglish()-s2.getEnglish():num3 ;
int num5 = (num4==0)?s1.getName().compareTo(s2.getName()):num4 ;
return num5;
}
}) ;
System.out.println("录入学生信息开始:");
//5个人
for(int x = 1 ; x <=5 ; x ++){
Scanner sc = new Scanner(System.in) ;
//为了方便:全部用String接收
System.out.println("请您输入第"+x+"个学生的姓名:");
String stuName = sc.nextLine() ;
System.out.println("请输入第"+x+"个学生的语文成绩:");
String chineseStr = sc.nextLine() ;
System.out.println("请输入第"+x+"个学生的数学成绩:");
String mathStr = sc.nextLine() ;
System.out.println("请输入第"+x+"个学生的英语成绩:");
String englishStr = sc.nextLine() ;
//封装学生对象
Student student = new Student() ;
student.setName(stuName) ;
student.setChinese(Integer.parseInt(chineseStr));
student.setMath(Integer.parseInt(mathStr));
student.setEnglish(Integer.parseInt(englishStr));
//添加到集合中
ts.add(student) ;
}
System.out.println("学生信息如下:");
System.out.println("姓名\t\t 语文成绩\t 数学成绩\t 英语成绩");
//遍历集合
for(Student s:ts){ System.out.println(s.getName()+"\t\t"+s.getChinese()+"\t"+s.getMath()+"\t"+s.getEnglish());
}
System.out.println("学生信息录入完毕;");
}
}
二、Map集合:
-
Map集合和Collection集合的区别?
Collection:单例集合:只能存储一种类型(引用类型)
Set集合和Map集合有一定的间接关系
HashSet的添加功能add依赖Map里面的HashMap<K,V>的put方法
TreeSet的add方法依赖于Map里面TreeMap<K,V>的put方法 -
Map:双列集合,可以存储键和值:两种类型
存储的一系列的键值对元素 Map集合:针对键有效,跟值无关,键必须唯一的!
默认的使用HashMap:允许元素出现null键和null值,线程不安全的类! -
Map集合的功能:
1). 添加
V put(K key,V value) :添加一个键值对元素注意事项: 细节:返回什么意思? 如果键是第一次添加,那么返回是null 如果键不是第一次添加,后面添加键对应的值将第一次的值覆盖掉,将第一次的值返回! 2). 删除 void clear() V remove(Object key):删除指定的键,返回被删除键对应的值 3). 判断 boolean containsKey(Object key):判断是否包含指定的键 boolean containsValue(Object value):判断是否包含指定的值 4). 获取 Collection<V> values():获取Map集合中的所有的值的集合 方式1:Map的遍历 Set<K> keySet():获取Map集合的中的所有的键 V get(Object key):然后在通过键获取值 方式2:Map的遍历 Set<Map.Entry<K,V>> entrySet():获取键值对对象
HashMap:底层数据结构:哈希表:键必须唯一的!存储和取出无序
4. JDK提供的类型
HashMap<String,String>
HashMap<Integer,Student> :学号 和学生
自定义类型:K
HahsMap<Student,String> 学生 朝代
哈希Map嵌套ArrayList或者ArrayList集合嵌套HashMap…
5. 键:自定义类型:如何保证key是唯一的呢?
put方法----依赖于hashCode和equals方法,存自定义对象所在类必须重写!
HashMap<String,String>:Key:String String类型底层重写hashCode和equals方法!
举例1:
public class Student {
private String name;
private int age;
public Student() {
}
public Student(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Student student = (Student) o;
if (age != student.age) return false;
return name != null ? name.equals(student.name) : student.name == null;
}
@Override
public int hashCode() {
int result = name != null ? name.hashCode() : 0;
result = 31 * result + age;
return result;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
public class HashMapDemo {
public static void main(String[] args) {
//创建一个Map集合对象
Map<String,String> map = new HashMap<String,String>() ;
// System.out.println(map);
//V put(K key,V value) :添加一个键值对元素
String value = map.put("文章", "马伊琍");
System.out.println(value);
String value2 = map.put("文章", "姚笛");
System.out.println(value2);
/* map.put("黄晓明","babay") ;
map.put("邓超","孙俪") ;
map.put("高圆圆","赵又廷") ;
map.put("向佐","郭碧婷") ;*/
System.out.println(map);
// void clear()
// * V remove(Object key):删除指定的键,返回被删除键对应的值
// map.clear();
// System.out.println(map.remove("邓超"));
// System.out.println(map);
/*
* boolean containsKey(Object key):判断是否包含指定的键
* boolean containsValue(Object value):判断是否包含指定的值
* */
/*System.out.println(map.containsKey("周杰伦"));
System.out.println(map.containsKey("黄晓明"));
System.out.println(map.containsValue("孙俪"));
// Collection<V> values():获取Map集合中的所有的值的集合
Collection<String> values = map.values() ;
for(String s:values){
System.out.println(s);
}*/
}
}
举例2:
public class HashMapDemo2 {
public static void main(String[] args) {
//遍历操作
// 方式1:Map的遍历(夫妻对) :推荐 第一种方式(常用的)
// Set<K> keySet():获取Map集合的中的所有的键 (获取所有的丈夫所在的集合)
// V get(Object key):然后在通过键获取值 (通过丈夫找妻子)
//创建HashMap集合对象
HashMap<String,String> hm = new HashMap<String,String>() ;
//添加元素
hm.put("杨过","小龙女") ;
hm.put("郭靖","黄蓉") ;
hm.put("陈玄风","梅超风") ;
hm.put("令狐冲","任盈盈") ;
//遍历:
Set<String> keySet = hm.keySet();
for(String key :keySet){
//在键获取值
//V get(Object key)
String value = hm.get(key);
System.out.println(key+"="+value);
}
System.out.println("----------------------------------------") ;
//方式2:Map的遍历(结婚证)
//Set<Map.Entry<K,V>> entrySet():获取键值对对象
//通过结婚证--->获取丈夫和妻子
//K getKey()
//V getValue()
Set<Map.Entry<String, String>> entrySet = hm.entrySet();
for(Map.Entry<String,String> entry:entrySet ){
//分别获取键和值
String key = entry.getKey();
String value = entry.getValue();
System.out.println(key+"="+value);
}
}
}
举例3:
public class HashMapDemo3 {
public static void main(String[] args) {
//创建HashMap集合对象
HashMap<Student,String> hm = new HashMap<Student,String>() ;
//创建学生对象
Student s1 = new Student("唐伯虎",35) ;
Student s2 = new Student("祝枝山",30) ;
Student s3 = new Student("宋江",38) ;
Student s4 = new Student("唐伯虎",35) ;
Student s5 = new Student("祝枝山",25) ;
//添加到集合中
hm.put(s1,"明朝") ;
hm.put(s2,"明朝") ;
hm.put(s3,"宋朝") ;
hm.put(s4,"宋朝") ;
hm.put(s5,"明朝") ;
//遍历
//获取所有的键的集合
Set<Student> keySet = hm.keySet();
for(Student s:keySet){
//通过键获取值
String value = hm.get(s);
System.out.println(s+"---"+value);
}
}
}
举例4:
public class Student implements Comparable<Student>{
private String name ;
private int age ;
public Student() {
}
public Student(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
@Override
public int compareTo(Student s) {
//主要条件:
//按照学生的年龄从小到大排序
int num = this.age-s.age ;
//年龄相同,不一定是同一个人,还需要比较姓名内容
int num2 = (num==0)?(this.name.compareTo(s.name)):num ;
return num2;
}
}
/* TreeMap:红黑树结构:进行元素排序
* 自然排序:TreeMap<K,V>()
* 比较器排序:TreeMap<K,V>(Comparator com)
*
*
* 需求: 键:自定义类型
* 使用TreeMap存储学生K:Student(name,age) 姓名---"给英文字母"
* V:爱好:String类型
*
*
* 主要条件: 按照学生的年龄从小到大排序 (自然排序,比较器排序)
*
* 使用keySet()遍历---通过键获取值
*/
public class TreeMapDemo {
public static void main(String[] args) {
//创建一个TreeMap集合对象:无参构造方法
//必须保证:键的类型必须实现 Comparable接口,重写compareTo方法
TreeMap<Student,String> tm = new TreeMap<Student,String>() ;
// TreeMap<Student,String> tm = new TreeMap<Student,String>(new Comparator<Student>(){
// //重写方法
// }) ;
//创建学生对象
Student s1 = new Student("gaoyuanyuan",41) ;
Student s2 = new Student("liushishi",45) ;
Student s3 = new Student("wuqilong",54) ;
Student s4 = new Student("wanglihong",35) ;
Student s5 = new Student("gaoyuanyuan",41) ;
Student s6 = new Student("gaoyuanyuan",30) ;
Student s7 = new Student("wenzhang",38) ;
Student s8 = new Student("wenzhang",35) ;
Student s9 = new Student("yangdecai",27) ;
tm.put(s1,"玩游戏") ;
tm.put(s2,"跑步") ;
tm.put(s3,"玩游戏") ;
tm.put(s4,"羽毛球") ;
tm.put(s5,"排球") ;
tm.put(s6,"篮球") ;
tm.put(s7,"足球") ;
tm.put(s8,"csgo") ;
tm.put(s9,"乒乓球") ;
//遍历
Set<Student> keySet = tm.keySet();
for(Student key:keySet){
String value = tm.get(key);
System.out.println(key+"---"+value);
}
}
}
三、Collections集合操作的工具类
-
针对集合操作的工具类
public static <T extends Comparable<? super T>> void sort(List list):针对List集合进行自然排序
public static void sort(List list,Comparator<? super T> c):针对List集合进行比较器排序
public static int binarySearch(List<<? extends Comparable<? super T>>, T key)
集合中的二分搜索 :前提条件:当前集合中的元素必须有序的!
public static void sort(List list,
Comparator<? super T> c):对列表元素进行随机置换
public static T max(Collection<? extends T> coll) :求最大值
public static T min(Collection<? extends T> coll):求最小值
举例:
public class CollectionsDemo {
public static void main(String[] args) {
//创建List集合对象
List<Integer> list = new ArrayList<Integer>() ;
list.add(20) ;
list.add(17) ;
list.add(19) ;
list.add(23) ;
list.add(21) ;
list.add(16) ;
list.add(24) ;
//public static <T extends Comparable<? super T>> void sort(List<T> list):针对List集合进行自然排序
System.out.println(list);
Collections.sort(list);
System.out.println(list);
//public static <T> int binarySearch(List<<? extends Comparable<? super T>>, T key)
int index = Collections.binarySearch(list,20) ;
System.out.println(index);
System.out.println("-------------------------------------");
Collections.shuffle(list); //随机置换
System.out.println(list);
System.out.println(Collections.max(list));
System.out.println(Collections.min(list));
//List<Student>:针对学生的年龄从小到大排序----->工具类:Collections.sort(list,new Comparator<Student>(){
// ...
//
// }) ;
}
}
举例:
/* 模拟斗地主的洗牌和发牌
* 情况1:不考虑每个手上牌上有序
* 步骤:
* 1)创建一个牌盒 ----->使用集合: ArrayList<String>
* 2)装牌
* 3)洗牌
* 4)发牌
* 5)看牌
* 问题:每个手上的无序的,如何保证每个人手上的牌有序!
*/
public class PokerDemo {
public static void main(String[] args) {
//创建一个牌盒
ArrayList<String> array = new ArrayList<String>() ;
//装牌
//创建点数数组
String[] numbers = {"A","2","3","4","5","6","7","8","9","10","J","Q","K"} ;
//创建花色数组
String[] colors = {"♥","♠","♣","♦"} ;
for(String number:numbers ){
for(String color:colors){
//使用字符串的拼接功能
String poker = color.concat(number);
//将扑克装到arrayList集合中
array.add(poker) ;
}
}
//装大王,和小王
array.add("小王") ;
array.add("大王") ;
// System.out.println(array);
//洗牌:随机置换
Collections.shuffle(array);
// System.out.println(array);
//发牌
//创建三个人
ArrayList<String> player1 = new ArrayList<String>() ;
ArrayList<String> player2 = new ArrayList<String>() ;
ArrayList<String> player3 = new ArrayList<String>() ;
ArrayList<String> diPai = new ArrayList<String>() ;
//A,B,C A--->B--->C
//遍历array :牌盒中的牌
for(int x = 0 ; x < array.size() ; x ++){
//规律
if(x>=array.size()-3){
//底牌
diPai.add(array.get(x)) ;
}else if(x % 3 == 0){
//玩家1
player1.add(array.get(x)) ;
}else if(x % 3 == 1){
//玩家2
player2.add(array.get(x)) ;
}else if(x % 3 == 2){
//玩家3
player3.add(array.get(x)) ;
}
}
//看牌:
//三个都可以看牌,并且看底牌
//可以将看牌封装成一个功能
lookPoker("高圆圆",player1);
lookPoker("赵又廷",player2);
lookPoker("耿明刚",player3);
lookPoker("底牌",diPai);
}
public static void lookPoker(String name,ArrayList<String> array){
System.out.print(name+"都的牌是:");
//遍历ArrayList
for(String s: array){
System.out.print(s+"\t");
}
System.out.println();
}
}
举例:
public class PokerTest {
public static void main(String[] args) {
//创建一个牌盒
HashMap<Integer,String> hm = new HashMap<Integer, String>() ;
//创建一个ArrayList:单独存储编号
ArrayList<Integer> array = new ArrayList<Integer>() ;
//编号是从0开始
int index = 0 ;
//装牌
//花色数组
//点数数组
String[] colors = {"♥","♠","♣","♦"} ;
String[] numbers = {"3","4","5","6","7","8","9","10","J","Q","K","A","2"} ;
for(String number: numbers){
for (String color:colors){
String poker = number.concat(color);
//装到HashMap集合中
hm.put(index,poker) ;
//将编号ArrayList集合中
array.add(index) ;
index ++ ;
}
}
//装小王和大王
hm.put(index,"小王") ;
array.add(index) ;
index ++ ;
hm.put(index,"大王") ;
array.add(index) ;
// System.out.println(array);
//洗牌洗的编号
Collections.shuffle(array);
// System.out.println(array);
//发牌:为了保证每一个牌是有序,使用TreeSet集合<Integer>:发的也是编号
TreeSet<Integer> player1 = new TreeSet<Integer>() ;
TreeSet<Integer> player2 = new TreeSet<Integer>() ;
TreeSet<Integer> player3 = new TreeSet<Integer>() ;
TreeSet<Integer> diPai = new TreeSet<Integer>() ;
//发牌
for(int x = 0 ; x < array.size() ; x ++){
if(x>=array.size()-3){
diPai.add(array.get(x)) ;
}else if(x % 3 ==0 ){
//玩家1
player1.add(array.get(x)) ;
}else if(x % 3 == 1){
//玩家2
player2.add(array.get(x)) ;
}else if(x % 3 == 2){
//玩家3
player3.add(array.get(x)) ;
}
}
//看牌: 封装一个功能
lookPoker("杨德财",hm,player1) ;
lookPoker("王思宇",hm,player2) ;
lookPoker("耿明刚",hm,player3) ;
lookPoker("底牌",hm,diPai) ;
}
//看牌的功能
public static void lookPoker(String name, HashMap<Integer,String> hashMap,
TreeSet<Integer> ts){
System.out.print(name+"的牌是:");
//遍历TreeSet集合---获取到每一个编号
for(Integer key: ts){
//在通过编号获取值: hashMap在这里去找
String value = hashMap.get(key);
System.out.print(value+"\t");
}
System.out.println();
}
}
四、线程
-
进程:由系统资源分配和调度的最小单元,而线程依赖于进程存在,程序执行的最小单位!
如果创建线程----必须有进程----->创建系统资源
Java语言不能够创建系统资源, 借助于底层语言C语言来操作
Java提供类Thread类 -
借助于Thread类如何实现 线程的创建?
并发:在一个时间点同时发生
并行:在一个时间段内同时发生 -
开发步骤:
1)自定义一个类 继承自 Thread(线程 是程序中的执行线程。Java 虚拟机允许应用程序并发地运行多个执行线程。 )
2)该子类应重写 Thread 类的 run 方法
3)创建当前子类对象,然后启动线程:start()而非run方法() -
启动线程:使用start 方法
成员方法:
设置线程名称
public final void setName(String name)
获取线程名称:
public final String getName()
举例:
/*方式1:使用的继承关系: 继承关系具有局限性
*/
public class MyThread extends Thread {
//重写run
//run里面:存放的耗时的代码:循环,io流读写操作...
@Override
public void run() {
for(int x = 0 ; x < 200 ; x ++){
// System.out.println(x);
System.out.println(getName()+":"+x);
}
}
}
public class ThreadDemo {
public static void main(String[] args) {
//创建子类对象
MyThread my = new MyThread() ;
//启动线程
//这个一线程对象将run方法调用两次
// my.run();
// my.run();
my.setName("杨德财");
my.start(); //调用start方法,是通过jvm调用run方法
//my.start(); //IllegalThreadStateException:非法状态异常
MyThread my2 = new MyThread() ;
my2.setName("高圆圆") ;
my2.start();
}
}
举例1:
public class ThreadYield extends Thread {
//三个线程都要执行
//ty1,ty2,ty3
@Override
public void run() {
for(int x = 0 ;x < 100 ; x ++){
System.out.println(getName()+":"+x);
Thread.yield(); //暂停当前的线程,执行其他线程!
}
}
}
/* public static void yield():暂停当前正在执行的线程,执行其他线程!
*/
public class ThreadYieldDemo {
public static void main(String[] args) {
//创建三个线程
ThreadYield ty1 = new ThreadYield() ;
ThreadYield ty2 = new ThreadYield() ;
ThreadYield ty3 = new ThreadYield() ;
ty1.setName("李渊");
ty2.setName("李世民");
ty3.setName("李元霸");
//开启线程
ty1.start();
ty2.start();
ty3.start();
}
}
举例2:
public class ThreadJoin extends Thread {
//重写run方法
@Override
public void run() {
for(int x = 0 ; x < 100 ; x ++){
System.out.println(getName()+":"+x);
}
}
}
/* public final void join()
* throws InterruptedException :等待该线程终止
*/
public class ThreadJoinDemo {
public static void main(String[] args) {
//创建两个线程
ThreadJoin tj1 = new ThreadJoin() ;
ThreadJoin tj2 = new ThreadJoin() ;
ThreadJoin tj3 = new ThreadJoin() ;
//设置名称
tj1.setName("令狐冲") ;
tj2.setName("东方不败") ;
tj3.setName("任盈盈") ;
tj1.start();
//try...catch...捕获异常
//throws:抛出异常:方法声明上
try {
tj1.join(); //等待tj1终止
} catch (InterruptedException e) {
e.printStackTrace();//日志: 跟踪堆栈,将异常信息打印在控制台上
}
tj2.start();
tj3.start();
}
}
举例3:
public class ThreadPriority extends Thread {
//创建3个线程
@Override
public void run() {
for(int x = 0 ; x < 100 ; x ++){
System.out.println(getName()+":"+x);
try {
Thread.sleep(2000);//线程睡眠2秒中:单位为毫秒
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
/* Thread类的常量字段表
* public static final int MAX_PRIORITY 10
* public static final int MIN_PRIORITY 1
* public static final int NORM_PRIORITY 5 :默认值
*
* public final void setPriority(int newPriority)设置优先级
* public final int getPriority()
*
*
* 优先级越大的线程,抢占CPU的执行权(cpu一点点时间片,可以高效的进行切换)的资格大
* 优先级越小的线程:抢占CPU的执行权越小!
*
* 线程的执行具有随机性!
*/
public class ThreadProrityDemo {
public static void main(String[] args) {
//创建三个线程类对象
ThreadPriority tp1 = new ThreadPriority() ;
ThreadPriority tp2 = new ThreadPriority() ;
ThreadPriority tp3 = new ThreadPriority() ;
tp1.setName("高圆圆");
tp2.setName("赵又廷");
tp3.setName("张佳宁");
//设置优先级
tp1.setPriority(10);
tp2.setPriority(1);
System.out.println(tp3.getPriority());//5
//启动线程
tp1.start();
tp2.start();
tp3.start();
}
}