JAVASE速通复习(二)
6 常见算法
6.1 排序算法
6.1.1 冒泡排序
核心就是每次从数组中找出最大值放到数组最后
import java.util.Arrays;public class test6 {public static void main(String[] args) {int [] arr = {5,2,3,1};//定义一个循环,控制排几轮for (int i = 0; i < 3; i++) {//定义一个循环每轮控制几次for (int j = 0; j < arr.length - i - 1; j++) {//如果大就交换if(arr[j] > arr[j+1]){int temp = arr[j];arr[j] = arr[j+1];arr[j+1] = temp;}}}System.out.println(Arrays.toString(arr));}
}
6.1.2 选择排序
核心是每轮选择当前位置,开始找出后边的较小值与该位置交换//其实就是选了最小的值放到了第一个位置。和冒泡排序不同的是,冒泡是两两比较,而比较的是定好位置比较
import java.util.Arrays;public class test7 {public static void main(String[] args) {int arr[] = {5,1,3,2};for (int i = 0; i < arr.length - 1; i++) {//控制几轮for (int j = i + 1; j < arr.length; j++) {if(arr[i] > arr[j]) {int temp = arr[i];arr[i] = arr[j];arr[j] = temp;}}}System.out.println(Arrays.toString(arr));}
}
6.1.3 二分查找*(有序)
public class test10 {public static void main(String[] args) {int arr[] = {7,23,79,81,103,127,256};System.out.println(binarySearch(arr, 81));}public static int binarySearch(int[] arr, int target) {int l = 0,r = arr.length-1;while(l<=r) {int mid = (l+r)/2;if(arr[mid]==target) {return mid;}else if(arr[mid]>target) {r = mid-1;}else{l = mid+1;}}return -1;}
}
7 正则表达式
7.1 概述

7.2 demo校验qq号是否合法
手写程序校验
public class demo1
{public static void main(String[] args) {System.out.println(checkQQ(null));System.out.println(checkQQ("4723897428478"));}public static boolean checkQQ(String qq){if(qq == null || qq.startsWith("0") || qq.length() < 6 || qq.length() > 20){return false;}//判断每个字符是否是数字for (int i = 0; i < qq.length(); i++) {char ch = qq.charAt(i);if(ch < '0' || ch > '9'){return false;}}return true;}
}
使用正则表达式
public static boolean checkQQ1(String qq){return qq != null && qq.matches("[1-9]\\d{5,19}");}7.3 书写规则
带中括号的内容只能匹配单个字符
预定义字符也只能匹配单个字符
切记不能出现中文
补充:


7.4 应用案例

7.4.1 验证手机号
package randomdemo;/** @author SHOWY*/import java.util.Scanner;public class phonedemo {public static void main(String[] args) {}public static void checkPhone(String phone){System.out.println("请输入你的电话号码");Scanner scanner = new Scanner(System.in);String phoneNum = scanner.nextLine();//13387383763 010-343434343434if(phoneNum.matches("1[3-9]\\d{9} | 0\\d{2,7}-?[1-9]\\d{4,19}")){System.out.println("您输入的号码格式正确");}else{System.out.println("您输入的号码格式不正确");}}
}
7.4.2 验证邮箱
public static void checkEmail(String mail){System.out.println("请输入你的电话邮箱");Scanner scanner = new Scanner(System.in);String mailnum = scanner.nextLine();//dsadasdasd@qq.com dashjdasdjh@qq.com.cnif(mailnum.matches("\\w{2,}@\\w{2,20}(\\.\\w{2,10}){1,2}")){System.out.println("您输入的邮箱格式正确");}else{System.out.println("您输入的邮箱格式不正确");}}7.5 正则表达式在一段内容中爬取信息

package randomdemo;/** @author SHOWY*/import java.util.regex.Matcher;
import java.util.regex.Pattern;public class demonew {public static void main(String[] args) {method1();}public static void method1() {String data = "电话 18827636726 18656455678" +"或者联系邮箱 dfhjkahds@qq.com" +"或者座机电话 010-98787898";//1.定义爬取规则String regex = "(\\w{2,}@\\w{2,20}(\\.\\w{2,10}){1,2}|(1[3-9]\\d{9}|0\\d{2,7}-?[1-9]\\d{4,19}))";//2.把正则表达式封装成一个pattern对象Pattern pattern = Pattern.compile(regex);//3.通过pattern对象去获取查找内容的匹配器对象Matcher matcher = pattern.matcher(data);//4.通过一个循环开始爬信息while (matcher.find()) {String rs = matcher.group();//获取到了找到的内容了System.out.println(rs);}}
}
7.6 用于搜索替换分割内容




注意这里s2.split()返回的是字符串的数组
8 异常
8.1 认识异常

8.2 处理方式
8.3 自定义异常

8.3.1 自定义运行时异常demo
import com.sun.corba.se.impl.resolver.SplitLocalResolverImpl;public class TestE {public static void main(String[] args) {try {saveAge(160);} catch (Exception e) {e.printStackTrace();System.out.println("底层出现了问题");}}public static void saveAge(int age){if(age > 0 && age < 150){System.out.println("年龄保存成功" + age);}else{throw new AgeIllegalRuntimeException("年龄非法,你的年龄是" + age);}}
}
public class AgeIllegalRuntimeException extends RuntimeException {public AgeIllegalRuntimeException() {}public AgeIllegalRuntimeException(String message) {super(message);}
}
8.3.2 自定义编译时异常demo
其实差不多的,只是更强烈,要求你一定去处理一下,你可以往上抛,方法+throws+ 这个异常
8.4 异常的处理

8.4.1 第一种处理

8.4.2 第二种处理

9 集合框架


9.1 Collection的集合特点 
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;public class TestCollection {public static void main(String[] args) {ArrayList<String> list = new ArrayList<>();//有序 可重复有索引list.add("java1");list.add("java2");list.add("java1");list.add("java2");System.out.println(list.get(1));System.out.println(list);HashSet<String> set = new HashSet<>();//无序 不重复无索引set.add("java1");set.add("java2");set.add("java1");set.add("java2");set.add("java3");System.out.println(set);}
}
9.2 Collection常见方法

红框部分的操作是把集合转成了指定格式的数组
addAll方法可以把一个集合的数据倒入到另一个之中去
9.3 Collection的遍历方式
9.3.1 迭代器

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;public class demo666 {public static void main(String[] args) {Collection<String> c = new ArrayList<>();c.add("a");c.add("b");c.add("c");c.add("d");//1.使用迭代器遍历集合//从集合对象中获取迭代器对象Iterator<String> it = c.iterator();while(it.hasNext()){//这个hashnet方法是调用迭代器String demo = it.next();System.out.println(demo);}}
}
9.3.2 增强for循环

public class demo666 {public static void main(String[] args) {Collection<String> c = new ArrayList<>();c.add("a");c.add("b");c.add("c");c.add("d");
//增加for循环既可以遍历数组又可以遍历集合for(String s : c){System.out.println(s);}}
}9.3.3 Lambda表达式遍历集合

9.4 案例遍历集合中的自定义对象


9.5 List集合
9.5.1 list集合特点和特有方法

9.5.2 遍历方式


9.5.3 ArrayList集合的底层原理


9.5.4 LinkedList集合的底层原理








9.6 Set集合
9.6.1 特点

9.6.2 HashSet集合的底层原理







注意:这里如果想要希望set集合认为2内容一样的对象是重复的

9.6.3 LinkedHashSet集合的底层原理

9.6.4 TreeSet集合底层原理



方式1 demo

方式2 demo

如果两种方式都有的话,TreeSet会就近选择自己自带的比较器对象进行排序

简化:


9.7 集合的并发修改异常问题
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.function.Consumer;public class demo666 {public static void main(String[] args) {List<String> list = new ArrayList<>();list.add("小李子1");list.add("小李子2");list.add("小李子3");list.add("小李子4");list.add("小子1");System.out.println(list);Iterator<String> it = list.iterator();while (it.hasNext()) {String name = it.next();if (name.contains("李")) {it.remove();//这个操作删除迭代器当前遍历的数据,每删除一个相当于底层做了一个i--}}System.out.println(list);}
}
如果以下这样是会报异常的

用增加for循环或者lambda表达式遍历集合不能解决这种并发修改异常的问题
10 Colletction的其他相关知识
10.1 前置知识:可变参数



10.2 collections工具类


10.3 综合案例

需要先来个Gamedemo主程序,创建一个room对象,然后后面写room类,room里必须有一副牌,所以先写card类
public class GameDemo {public static void main(String[] args) {//1.牌类//2,房间Room room = new Room();}
}
public class Card {private String number;private String color;//每张牌是有大小的private int size;//提供一个无参构造器public Card(){}public Card(String number, String color,int size) {this.number = number;this.size = size;this.color = color;}public String getNumber() {return number;}public void setNumber(String number) {this.number = number;}public String getColor() {return color;}public void setColor(String color) {this.color = color;}public int getSize() {return size;}public void setSize(int size) {this.size = size;}@Overridepublic String toString() {return color + number + " (" + size + ")";}
}
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;public class Room {//必须有一副牌private List<Card> allCards = new ArrayList<Card>();public Room(){//1.做出54张排,存入到集合Allcards里面//a. 点数 个数 类型确定String[] num = {"3","4","5","6","7","8","9","10","J","Q","K","2"};//b.花色String[] col = {"♣","♠","♦","♥"};//c.遍历点数,内部遍历花色int size = 0;//表示每张牌的大小for (String nums : num) {size ++;for (String colo : col) {//得到一张牌Card e = new Card(nums,colo,size);allCards.add(e);}}Card c2 = new Card("","🤡",++size);Card c1 = new Card("","🃏",++size);Collections.addAll(allCards,c2,c1);System.out.println("新牌" + allCards);}
}
做牌就做好了,接下来是开始洗牌 发牌 对牌排序等等
import java.util.*;public class Room {//必须有一副牌private List<Card> allCards = new ArrayList<Card>();public Room(){//1.做出54张排,存入到集合Allcards里面//a. 点数 个数 类型确定String[] num = {"3","4","5","6","7","8","9","10","J","Q","K","2"};//b.花色String[] col = {"♣","♠","♦","♥"};//c.遍历点数,内部遍历花色int size = 0;//表示每张牌的大小for (String nums : num) {size ++;for (String colo : col) {//得到一张牌Card e = new Card(nums,colo,size);allCards.add(e);}}Card c2 = new Card("","🤡",++size);Card c1 = new Card("","🃏",++size);Collections.addAll(allCards,c2,c1);System.out.println("新牌" + allCards);}//游戏启动方法public void start(){//1.洗牌Collections.shuffle(allCards);System.out.println("洗牌后" + allCards);//2.发牌,首先定义三个玩家List<Card> xiaohong = new ArrayList<>();List<Card> xiaomei = new ArrayList<>();List<Card> xiaoming = new ArrayList<>();for(int i = 0; i < allCards.size() - 3; i++){Card c = allCards.get(i);if(i % 3 == 0){xiaohong.add(c);}else if(i % 3 == 1){xiaomei .add(c);}else{xiaoming .add(c);}}//3.对三个玩家的牌进行排序sortcards(xiaomei);sortcards(xiaohong);sortcards(xiaoming);//4.看牌List<Card> lastthreecard = allCards.subList(allCards.size() - 3, allCards.size());//包前不包后xiaomei.addAll(lastthreecard);//地主牌扔进去sortcards(xiaomei);System.out.println("xiaohong:" + xiaohong);System.out.println("xiaomei:" + xiaomei);System.out.println("xiaoming:" + xiaoming);}
//对牌排序private void sortcards(List<Card> cards) {Collections.sort(cards, new Comparator<Card>() {@Overridepublic int compare(Card o1, Card o2) {return o1.getSize() - o2.getSize();//升序}});}
}
11 Map集合

11.1 简述


11.2 常用方法




11.3 遍历方式

11.3.1 键找值

import java.util.HashMap;
import java.util.Map;
import java.util.Set;public class BIANLIMAP {public static void main(String[] args) {Map<String , Double> map = new HashMap<>();map.put("A", 1.0);map.put("B", 2.0);map.put("C", 3.0);map.put("D", 4.0);map.put("E", 5.0);System.out.println(map);//1.获取map全部的键Set<String> keys = map.keySet();System.out.println(keys);for (String key : keys) {double value = map.get(key);System.out.println(key + value);}}
}
11.3.2 键值对
把每一组键值对封装成键值对对象

public class BIANLIMAP {public static void main(String[] args) {Map<String , Double> map = new HashMap<>();map.put("A", 1.0);map.put("B", 2.0);map.put("C", 3.0);map.put("D", 4.0); map.put("E", 5.0);System.out.println(map);Set<Map.Entry<String, Double>> entries = map.entrySet();for (Map.Entry<String, Double> entry : entries) {String key = entry.getKey();Double value = entry.getValue();System.out.println(key + ":" + value);}}
}
11.3.3 lambda表达式
import java.util.HashMap;
import java.util.Map;
import java.util.Set;public class BIANLIMAP {public static void main(String[] args) {Map<String , Double> map = new HashMap<>();map.put("A", 1.0);map.put("B", 2.0);map.put("C", 3.0);map.put("D", 4.0);map.put("E", 5.0);System.out.println(map);map.forEach((k,v) ->{System.out.println(k + "====>" + v);});}
}
11.3.4 案例

import java.util.*;public class lianxi {public static void main(String[] args) {List<String> data = new ArrayList<String>();String[] selects = {"A","B","C","D"};Random rand = new Random();for (int i = 0; i <=80; i++) {int index = rand.nextInt(4);//0 1 2 3data.add(selects[index]);}System.out.println(data);//统计每个景点的投票人数//准备一个map集合统计最终的结果Map<String,Integer> result = new HashMap<>();for (String s : data) {//问一下map集合是否存在该景点if(result.containsKey(s)){//说明统计过,其值+1,重新存入到mapresult.put(s,result.get(s) + 1);}else{result.put(s, 1);}}System.out.println(result);}
}
11.4 HashMap


如果是这样的话
import java.util.HashMap;
import java.util.Map;public class HashMapdemo {public static void main(String[] args) {Map<student,String> map = new HashMap<student,String>();map.put(new student("John",12),"John");map.put(new student("John",12),"John1");map.put(new student("tom",22),"John2");map.put(new student("jerry",28),"John3");System.out.println(map);}
}
他输出4个值,不会认为前两个是重复的键

所以重写一个equals,让其哈希值一样,就会只留一个元素
import java.util.Objects;public class student {String name;int age;public student(String name, int age) {this.name = name;this.age = age;}@Overridepublic boolean equals(Object object) {if (this == object) return true;if (object == null || getClass() != object.getClass()) return false;student student = (student) object;return age == student.age && Objects.equals(name, student.name);}@Overridepublic int hashCode() {return Objects.hash(name, age);}
}
11.5 LinkedHashMap

11.6 TreeMap

方式1

方式2
因为这个比较器对象离着这个集合更近,所以他会用比较器对象,所以是年龄的降序排序

12 补充:集合的嵌套
12.1 定义
集合中的元素又是一个集合


取值的话这么取
13 JDK8新特性
13.1 Stream



stream流支持链式编程

13.2 Stream流的使用步骤

13.3 获取stream流


如果要整体处理Map


13.4 stream流的中间方法

import javax.xml.crypto.dsig.spec.XSLTTransformParameterSpec;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.stream.Stream;public class StreamTest {public static void main(String[] args) {List<student> students = new ArrayList<>();student s1 = new student("lili2",26,172.5);student s2 = new student("lili2",26,172.5);student s3 = new student("lili3",23,167.6);student s4 = new student("lili4",25,169.0);student s5 = new student("lili5",35,183.8);student s6 = new student("lili6",34,168.5);Collections.addAll(students, s1, s2, s3, s4, s5, s6);//需求找出年龄大于等于23 且年龄小于等于30的并降序排序students.stream().filter(s -> s.getAge() >= 23 && s.getAge() <= 30).sorted((o1,o2) -> o2.getAge() - o1.getAge()).forEach(s -> System.out.println(s));//需求 取出身高最高的3名学生 并输出students.stream().sorted((o1,o2) -> Double.compare(o2.getHeight(),o1.getHeight())).limit(3).forEach(s -> System.out.println(s));//需求 取出身高倒数的2名学生 并输出students.stream().sorted((o1,o2) -> Double.compare(o2.getHeight(),o1.getHeight())).skip(students.size() - 2).forEach(s -> System.out.println(s));//需求 找出身高超过168的学生叫什么,要求去除重复的名字 再输出,map其实就是加工students.stream().filter(s -> s.getHeight() > 168).map(s -> s.getName()).distinct().forEach(s -> System.out.println(s));//distinct 去重复自定义类型的对象(希望内容一样就认为重复 重写hashcode和equals)students.stream().filter(s -> s.getHeight() > 167).distinct().forEach(s -> System.out.println(s));Stream<String> st1 = Stream.of("111", "222");Stream<String> st2 = Stream.of("112", "223");Stream<String> concat = Stream.concat(st1, st2);concat.forEach(s -> System.out.println(s));}
}

13.5 Stream流常见的终结方法


import javax.xml.crypto.dsig.spec.XSLTTransformParameterSpec;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;public class StreamTest {public static void main(String[] args) {List<student> students = new ArrayList<>();student s1 = new student("lili2", 26, 172.5);student s2 = new student("lili2", 26, 172.5);student s3 = new student("lili3", 23, 167.6);student s4 = new student("lili4", 25, 169.0);student s5 = new student("lili5", 35, 183.8);student s6 = new student("lili6", 34, 168.5);Collections.addAll(students, s1, s2, s3, s4, s5, s6);//需求 :计算超过168的学生有几人long count = students.stream().filter(s -> s.getHeight() > 168).count();System.out.println(count);//需求 :找出身高最高的学生对象,输出student student = students.stream().max((o1, o2) -> Double.compare(o1.getHeight(), o2.getHeight())).get();System.out.println(student);//需求: 找出身高高于170的学生对象,并放到一个新的集合中返回//流只能收集一次List<student> students1 = students.stream().filter(a -> a.getHeight() > 170).collect(Collectors.toList());System.out.println(students1);Set<student> students2 = students.stream().filter(a -> a.getHeight() > 170).collect(Collectors.toSet());//去重了System.out.println(students2);//需求: 找出身高高于170的学生对象,把学生对象的名字身高存入到一个map中Map<String, Double> students3 = students.stream().filter(s -> s.getHeight() > 170).distinct().collect(Collectors.toMap(a -> a.getName(), a -> a.getHeight()));System.out.println(students3);}
}

