算法(选择排序、冒泡排序、二分查找)
选择排序
每轮选择当前位置,开始找出后面的较小值与该位置交换。
选择排序的关键:
确定总共需要选择几轮:数组的长度-1。
控制每轮从以前位置为基准,与后面元素选择几次。
冒泡排序
每次从数组中找出最大值放在数组的后面去。
实现冒泡排序的关键步骤分析:
确定总共需要做几轮:数组的长度-1。
当前位置大于后一个位置则交换数据。
package com.tichinajie.d1_aigorithm;
import java.util.Arrays;
public class Test1 {
public static void main(String[] args) {
//选择排序
int[] arr = {12,14,23,11,21,5,2,8,9,29,19,10};
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[j];
arr[j] = arr[i];
arr[i] = temp;
}
}
}
System.out.println(Arrays.toString(arr));
}
}
package com.tichinajie.d1_aigorithm;
import java.util.Arrays;
public class Test2 {
public static void main(String[] args) {
//冒泡排序
int[] arr = {2,4,7,5,8,9,0,1};
for (int i = 0; i < arr.length - 1; i++) {
for (int j = 0; j < arr.length - i - 1; j++) {
if (arr[j] > arr[j + 1]) {
int temp = arr[j + 1];
arr[j + 1] = arr[j];
arr[j] = temp;
}
}
}
System.out.println(Arrays.toString(arr));
}
}
package com.tichinajie.d1_aigorithm;
import java.util.Arrays;
public class Test3 {
public static void main(String[] args) {
//选择排序
int[] arr = {12,14,23,11,21,5,2,8,9,29,19,10};
//算法优化
for (int i = 0; i < arr.length - 1; i++) {
int minIndex = i;
for (int j = i + 1; j < arr.length; j++) {
if (arr[minIndex] > arr[j]) {
minIndex = j;
}
}
if (i != minIndex){
int temp = arr[minIndex];
arr[minIndex] = arr[i];
arr[i] = temp;
}
}
System.out.println(Arrays.toString(arr));
}
}
二分查找法
package com.tichinajie.d1_aigorithm;
import java.util.Arrays;
public class Test4 {
public static void main(String[] args) {
//二分查找法查找数组中的元素
int[] arr = {12,13,15,36,57,99};
System.out.println(binarySearch(arr, 13));
System.out.println(Arrays.binarySearch(arr, 12));
}
public static int binarySearch(int[] arr,int data){
int left = 0;
int right = arr.length - 1;
while (left <= right){
int middle = (left+right)/2;
if (data > arr[middle]){
left = middle + 1;
}else if (data < arr[middle]){
right = middle - 1;
}else {
return middle;
}
}
return -1;//特殊结果,代表没有找到数据,数组中不存在该数据
}
}
正则表达式
正则表达式就是由一些特殊的字符组成,代表的是一个规则。
作用一:用来校验数据是否合法
作用二:在一段文本中查找满足要求的内容
package com.tichinajie.d2_regex;
/*
* 目标:体验一下使用正则表达式来校验数据格式的合法性。
需求:校验QQ号码是否正确,要求全部是数字,长度是(6-20)之间,不能以0开头。
* */
public class RegexTest1 {
public static void main(String[] args) {
System.out.println(checkQQ("242343456"));
System.out.println(checkQQ("0482734234"));
System.out.println(checkQQ(null));
System.out.println(checkQQ("r3423rr565"));
System.out.println(checkQQ("12345"));
System.out.println(checkQQ("223423534556457567568676785745634523"));
System.out.println("------------------------------------------------------------------------");
System.out.println(checkQQ2("242343456"));
System.out.println(checkQQ2("0482734234"));
System.out.println(checkQQ2(null));
System.out.println(checkQQ2("r3423rr565"));
System.out.println(checkQQ2("12345"));
System.out.println(checkQQ2("223423534556457567568676785745634523"));
}
//使用正则表达式
public static boolean checkQQ2(String qq){
return qq != null && qq.matches("[1-9]\\d{5,19}");
}
public static boolean checkQQ(String qq){
//看是否满足基本条件
if (qq ==null || qq.length() < 6 || qq.length() > 20 || qq.startsWith("0")){
return false;
}
//判断是否有字母
for (int i = 0; i < qq.length(); i++) {
char ch = qq.charAt(i);
if (ch < '0' || ch > '9'){
return false;
}
}
return true;
}
}
正则表达式的书写规则
判断字符串是否匹配正则表达式,匹配返回true,不匹配返回false。
正则表达式的是写规则:
字符类(只匹配单个字符)
预定义字符(只匹配单个字符)
数量词
package com.tichinajie.d2_regex;
//掌握正则表达式的书写规则
public class RegexTest2 {
public static void main(String[] args) {
//1、字符类(只能匹配单个字符)
System.out.println("a".matches("[abc]")); //[abc]只能匹配a、b、c
System.out.println("e".matches("[abcd]")); // false
System.out.println("d".matches("[^abc]")); //[^abc]不能是abc
System.out.println("a".matches("[^abc]")); // false
System.out.println("b".matches("[a-zA-z]")); // [a-zA-Z] 只能是a-z A-Z的字符
System.out.println("2".matches("[a-zA-Z]")); // false
System.out.println("k".matches("a-z && [^bc]")); // :a到z,除了b和c
System.out.println("b".matches("a-z && [^bc]")); // false
System.out.println("ab".matches("[a-zA-Z0-9]"));//false 注意:以上带[内容]的规则都只能用于匹配单个字符
//2、预定义字符(只能匹配单个字符).\d \D \s \s \w \W
System.out.println("徐".matches("."));//.可以匹配任意字符
System.out.println("徐徐".matches(".")); // false
//\在Java中有特殊意义:\n换行\t代表一个缩进
//如果在java中,希望\就是\必须转义
System.out.println("\"");
System.out.println("3".matches("\\d")); // \d: 0-9
System.out.println("a".matches("\\d")); //false
System.out.println(" ".matches("\\s")); //s:代表一个空白字符
System.out.println("a".matches("\\s")); // false
System.out.println("a".matches("\\S"));//\S:代表一个非空白字符
System.out.println("".matches("\\S"));//false
System.out.println("a".matches("\\w"));//\w:[a-zA-Z_0-9]
System.out.println("_".matches("\\w"));//true
System.out.println("".matches("\\w"));//false
System.out.println("徐".matches("\\W"));//[^\w]不能是a-zA-Z_0-9
System.out.println("a".matches("\\W"));//false
System.out.println("23232".matches("\\d"));//false注意:以上预定义字符都只能匹配单个字符
//3、数量词:? * + {n} {n,} {n,m}
System.out.println("a".matches("\\w?"));//? 代表0次或1次
System.out.println(" ".matches("\\w?"));//true
System.out.println("abc".matches("\\w?"));//false
System.out.println("abcI2".matches("\\w*"));//*代表0次或多次
System.out.println("".matches("\\w*"));//true
System.out.println("abc12".matches("\\w*"));//false
System.out.println("a3c".matches("\\w{3}"));//{3}代表要正好是n次
System.out.println("abcd".matches("\\w{3}"));//false
System.out.println("abcd".matches("\\w{3,}"));//{3,}代表是>=3次
System.out.println("ab".matches("\\w{3,}"));//false
System.out.println("abcde徐".matches("\\w{3,}"));//false
System.out.println("abc232d".matches("\\w{3,9}"));//{3,9}代表是 大于等于3次,小于等于9次
//4、其他几个常用的符号:(?i) 忽略大小写、 或:|、分组:()
System.out.println("----------------------------------------------");
System.out.println("abc".matches("(?i)abc"));//true
System.out.println("ABC".matches("(?i)abc"));//true
System.out.println("aBc".matches("a((?i)b)c"));//true
System.out.println("ABc".matches("a((?i)b)c"));//false
//需求1:要求要么是3个小写字母,要么是3个数字。
System.out.println("123".matches("\\d{3}|[a-z]{3}"));
System.out.println("abc".matches("\\d{3}|[a-z]{3}"));
System.out.println("aAc".matches("\\d{3}|[a-z]{3}"));
//需求2:必须是“我爱“开头,中间可以是至少一个"编程“,最后至少是1个"666"
System.out.println("我爱编程编程666666".matches("我爱(编程)+(666)+"));
System.out.println("我爱编程编程6666666".matches("我爱(编程)+(666)+"));//false
}
}
正则表达式的应用
1、用于校验数据
package com.tichinajie.d2_regex;
import java.util.Scanner;
public class RegexTest3 {
public static void main(String[] args) {
//正则表达式的应用一,校验数据格式是否合法
checkEmail();
}
public static void checkPhone(){
Scanner sc = new Scanner(System.in);
while (true){
System.out.println("请您输入您的电话号码(手机I座机):");
String phone = sc.nextLine();
//18676769999 010-3424242424 0104644535
if(phone.matches( "(1[3-9]\\d{9})|(0\\d{2,7}-?[1-9]\\d{4,19})")){
System.out.println("您输入的号码格式正确~~~");
break;
}else {
System.out.println("您输入的号码格式不正确~~~");
}
}
}
public static void checkEmail(){
while (true) {
System.out.println("请您输入您的邮箱:");
Scanner sc = new Scanner(System.in);
String email = sc.nextLine();
/**
* dlei0009@163.com
*25143242@qq.com
*itheima@itcast.com.cn
*/
if(email.matches("\\w{2,}@\\w{2,20}(\\.\\w{2,10}){1,2}")){
System.out.println("您输入的邮箱格式正确~~~");
break;
}else{
System.out.println("您输入的邮箱格式不正确~~~");
}
}
}
}
2、用于查找信息
package com.tichinajie.d2_regex;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class RegexTest4 {
public static void main(String[] args) {
//使用正则表达式
method1();
}
//需求1:从以下内容中爬取出,手机,邮箱,座机、400电话等信息。
public static void method1() {
String data = "来黑马程序员学习Java,\n" +
"电话:1866668888,18699997777\n" +
"或者联系邮箱:boniu@itcast.cn,\n" +
"座机电话:01036517895,010-98951256\n" +
"邮箱:bozai@itcast.cn,\n" +
"邮箱:dlei0009@163.com,\n" +
"热线电话: 400-618-9090,400-618-4000,4006184000,4006189090";
//1、定义爬取规则
String regex = "(1[3-9]\\d{9})|(0\\d{2,7}-?[1-9]\\d{4,19})|\\w{2,}@\\w{2,20}(\\.\\w{2,10}){1,2}"
+ "|(400-?\\d{3,7}-?\\d{3,7})";
//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);
}
}
}
3、用于搜索替换、分割内容
正则表达式用于搜索替换、分割内容,需要结合String提供的如下方法完成:
package com.tichinajie.d2_regex;
import java.util.Arrays;
/**
*目标:掌握使用正则表达式做搜索替换,内容分割。
*/
public class RegexTest5 {
public static void main(String[] args) {
//1、public String replaceAll(String regex,String newStr):按照正则表达式匹配的内容进行替换
//需求1:请把古力娜扎ai8888迪丽热巴999aa5566马尔扎哈fbbfsfs42425卡尔扎巴,中间的非中文字符替换成"-"
String s1="古力娜扎ai8888迪丽热巴999aa5566马尔扎哈fbbfsfs42425卡尔扎巴";
System.out.println(s1.replaceAll("\\w+","-"));
//需求2(拓展):某语音系统,收到一个口吃的人说的“我我我喜欢编编编编编编编编编编编编程程程!”,需要优化成“我喜欢编程!"。
String s2="我我我喜欢编编编编编编编编编编编编程程程";
/**
*(.)一组:.匹配任意字符的。
*\\:为这个组声明一个组号:1号
*+:声明必须是重复的字
*$1可以去到第1组代表的那个重复的字
*/
System.out.println(s2.replaceAll("(.)\\1+","$1"));
//2、public String.[]split(String regex.):按照正则表达式匹配的内容进行分割字符串,反回一个字符串数组。
//需求1:请把古力娜扎ai8888迪丽热巴999aa5566马尔扎哈fbbfsfs.42425卡尔扎巴,中的人名获取出来。
String s3="古力娜扎ai8888迪丽热巴999aa5566马尔扎哈fbbfsfs42425卡尔扎巴";
String[] names = s3.split("\\w+");
System.out.println(Arrays.toString(names));
}
}
异常
异常的体系
Error:代表的系统级别错误(属于严重问题),也就是说系统一旦出现问题,Sun公司会把这些问题封装成Error对象给出来,说白了,Error是给sun公司自己用的,不是给我们程序员用的,因此我们开发人员不用管它。
Exception:叫异常,它代表的才是我们程序可能出现的问题,所以,我们程序员通常会用Exception以及它的孩子来封装程序出现的问题。
1、运行时异常:RuntimeException及其子类,编译阶段不会出现错误提醒,运行时出现的异常(如:数组索引越界异常)。
2、编译时异常:编译阶段就会出现错误提醒的(如:日期解析异常)。
抛出异常(throws)
在方法上使用throws:关键字,可以将方法内部出现的异常抛出去给调用者处理。
捕获异常(try...catch)
直接捕获程序出现的异常
package com.tichinajie.d3_exception;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
/*
* 目标:认识异常
* */
public class ExceptionTest1 {
public static void main(String[] args) throws ParseException {
// Integer.valueOf("abc");
// int[] arr = {11, 22, 33};
// System.out.println(arr[5]);
SimpleDateFormat sdf = new SimpleDateFormat( "yyyy-MM-dd HH:mm:ss");
Date d = sdf.parse("2028-11-11 10:24");
// Date d = null;
// try {
// d = sdf.parse("2028-11-11 10:24");
// } catch (ParseException e) {
// throw new RuntimeException(e);
// }
System.out.println(d);
}
}
自定义异常
Java无法为这个世界上全部的问题都提供异常类来代表,如果企业自己的某种问题,想通过异常来表示,以便用异常来管理该问题,那就需要自己来定义异常类了。
自定义异常的种类
package com.tichinajie.d3_exception;
//1、必须让这个类继承自RunTimeException,才能成为一个运行时异常类
public class AgeIllegalRuntimeException extends RuntimeException {
public AgeIllegalRuntimeException() {
}
public AgeIllegalRuntimeException(String message) {
super(message);
}
}
package com.tichinajie.d3_exception;
//1、必须让这个类继承自RunTimeException,才能成为一个运行时异常类
public class AgeIllegalException extends RuntimeException {
public AgeIllegalException() {
}
public AgeIllegalException(String message) {
super(message);
}
}
package com.tichinajie.d3_exception;
/*
* 目标:掌握自定义异常,异常的应用
* */
public class ExceptionTest2 {
public static void main(String[] args) {
//需求:保存一个合法的年龄
try{
saveAge(15) ;
System.out.println("底层执行成功的!");
} catch (Exception e) {
e.printStackTrace();
System.out.println("底层出现了bug!");
}
try{
saveAge2(25);
System.out.println("saveAge2底层执行是成功的!");
} catch (AgeIllegalException e){
e.printStackTrace();
System.out.println("saveAge2底层执行是出现bug的!");
}
}
public static void saveAge2(int age) throws AgeIllegalException{
if(age > 0 && age < 150){
System.out.println("年龄被成功保存:" + age);
} else {
//用一个异常对象封装这个问题
//throw抛出去这个异常对象
//throws 用在方法上,抛出方法内部的异常
throw new AgeIllegalException("/age is illegal, your age is " + age);
}
}
public static void saveAge(int age){
if(age > 0 && age < 150){
System.out.println("年龄被成功保存:" + age);
} else {
//用一个异常对象封装这个问题
//throw抛出去这个异常对象
throw new AgeIllegalRuntimeException("/age is illegal, your age is " + age);
}
}
}
异常的处理
开发中对于异常的常见处理方式:
package com.tichinajie.d3_exception;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
/*
* 目标异常处理
* */
public class ExceptionTest3 {
public static void main(String[] args) {
try {
test1();
} catch (FileNotFoundException e) {
System.out.println("您要找的文件不存在~~");
throw new RuntimeException(e);//打印这个异常对象的信息,记录下来
} catch (ParseException e) {
System.out.println("您要解析的时间有问题~~");
throw new RuntimeException(e);//打印这个异常对象的信息,记录下来
}
}
private static void test1() throws FileNotFoundException, ParseException {
SimpleDateFormat sdf = new SimpleDateFormat( "yyyy-MM-dd HH:mm:ss");
Date d = sdf.parse("2028-11-11 10:24");
System.out.println(d);
test2();
}
public static void test2() throws FileNotFoundException {
//读取文件的
InputStream is = new FileInputStream("D:/meinv.png");
}
}
package com.tichinajie.d3_exception;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
/*
* 目标异常处理
* */
public class ExceptionTest3_2 {
public static void main(String[] args) {
try {
test1();
} catch (Exception e) {
System.out.println("您要找的文件不存在~~");
e.printStackTrace();//打印这个异常对象的信息,记录下来
}
}
private static void test1() throws Exception {
SimpleDateFormat sdf = new SimpleDateFormat( "yyyy-MM-dd HH:mm:ss");
Date d = sdf.parse("2028-11-11 10:24");
System.out.println(d);
test2();
}
public static void test2() throws Exception {
//读取文件的
InputStream is = new FileInputStream("D:/meinv.png");
}
}
package com.tichinajie.d3_exception;
import java.util.Scanner;
public class ExceptionTest4 {
public static void main(String[] args) {
//需求:调用一个方法,让用户输入一个合适的价格返回为止
while (true) {//尝试修复
try {
System.out.println(getMoney());
} catch (Exception e) {
System.out.println("请您输入合法的数字!!");
}
}
}
public static double getMoney(){
Scanner sc = new Scanner(System.in);
System.out.println("请输入合适的价格:");
double money = sc.nextDouble();
if (money >= 0){
return money;
}else {
System.out.println("你输入的价格不合适");
}
return money;
}
}
(本章图片均来自于黑马程序员视频)