第1章数组冒泡排序和Arrays工具类
1.1数组的冒泡排序
冒泡排序:就是相邻的两个元素进行两两比较,把元素值大的元素依次向后排.
1.1.1数组排序之冒泡排序原理图解
1.1.2数组排序之冒泡排序代码实现
1.1.2.1案例代码一:
package javalearning;
/*
* 数组排序:(冒泡排序)
*/
public class ArrayDemo {
public static void main(String[] args) {
//定义一个int类型的数组
int[] arr = {24,69,80,57,13};
/*
//第一次比较
//arr.length-1是为了防止索引越界,否则arr[x+1]会越界
//arr.length-1-0是为了减少比较的个数(这是冒泡排序的特点,每次比较都少一个元素,详见上图)
for(int x=0; x<arr.length-1-0; x++) {
if(arr[x] > arr[x+1]) {
//交换数据
int temp = arr[x];
arr[x] = arr[x+1];
arr[x+1] = temp;
}
}
//调用遍历方法
System.out.println("第一次比较完毕:");
printArray(arr);
//第二次比较
//arr.length-1是为了防止索引越界
//arr.length-1-1是为了减少比较的次数
for(int x=0; x<arr.length-1-1; x++) {
//ArrayIndexOutOfBoundsException
if(arr[x] > arr[x+1]) {
//交换数据
int temp = arr[x];
arr[x] = arr[x+1];
arr[x+1] = temp;
}
}
//调用遍历方法
System.out.println("第二次比较完毕:");
printArray(arr);
//第三次比较
//arr.length-1是为了防止索引越界
//arr.length-1-2是为了减少比较的次数
for(int x=0; x<arr.length-1-2; x++) {
//ArrayIndexOutOfBoundsException
if(arr[x] > arr[x+1]) {
//交换数据
int temp = arr[x];
arr[x] = arr[x+1];
arr[x+1] = temp;
}
}
//调用遍历方法
System.out.println("第三次比较完毕:");
printArray(arr);
//第四次比较
//arr.length-1是为了防止索引越界
//arr.length-1-3是为了减少比较的次数
for(int x=0; x<arr.length-1-3; x++) {
//ArrayIndexOutOfBoundsException
if(arr[x] > arr[x+1]) {
//交换数据
int temp = arr[x];
arr[x] = arr[x+1];
arr[x+1] = temp;
}
}
//调用遍历方法
System.out.println("第四次比较完毕:");
printArray(arr);
*/
//用循环改进
/*
for(int y=0; y<4; y++) {
for(int x=0; x<arr.length-1-y; x++) {
if(arr[x] > arr[x+1]) {
//交换数据
int temp = arr[x];
arr[x] = arr[x+1];
arr[x+1] = temp;
}
}
}
*/
/*
//循环做的次数不能写固定的值,用arr.length-1改进即可
for(int y=0; y<arr.length-1; y++) {
for(int x=0; x<arr.length-1-y; x++) {
if(arr[x] > arr[x+1]) {
//交换数据
int temp = arr[x];
arr[x] = arr[x+1];
arr[x+1] = temp;
}
}
}
printArray(arr);
*/
//如果我有多个数组要排序,每个数组写这样的一段代码,太麻烦,怎么办呢
//用方法改进
sort(arr);//调用以后arr已经变成排序后的了
System.out.println("排序后:");
printArray(arr);
}
/*
* 两个明确:
* 返回值类型:void(正常来说返回的应是一个排序号的数组,但是因为数组是引用类型,所以形参的改变会直接影响实参,调用方法时传的这个数组在调用方法完毕后就已经完成排序了,所以用viod即可)
* 参数列表:int[] arr
*/
public static void sort(int[] arr) {
for(int x=0; x<arr.length-1; x++) {
for(int y=0; y<arr.length-1-x; y++) {
if(arr[y] > arr[y+1]) {
int temp = arr[y];
arr[y] = arr[y+1];
arr[y+1] = temp;
}
}
}
}
/*
* 数组遍历
*/
public static void printArray(int[] arr) {
System.out.print("[");
for(int x=0; x<arr.length; x++) {
if(x==arr.length-1) {
System.out.print(arr[x]);
}else {
System.out.print(arr[x]+", ");
}
}
System.out.println("]");
}
}
1.2Arrays工具类
1.2.1Arrays类的概述和使用
Arrays:提供了对数组操作的各种方法。
查看API发现:
在java.util里,不在java.lang下,因此要导包
所有成员方法都被static修饰
没有看到构造方法。
该类的常用方法:
public static String toString(int[] a):把数组转成字符串
public static void sort(int[] a):对数组进行升序排序(从小到大)
1.2.1.1案例代码二
package javalearning;
import java.util.Arrays;
/*
* Arrays:提供了对数组操作的各种方法。
* public static String toString(int[] a):把数组转成字符串
* public static void sort(int[] a):对数组进行升序排序(从小到大)
*/
public class ArraysDemo {
public static void main(String[] args) {
//定义一个数组
int[] arr = {24,69,80,57,13};
//public static String toString(int[] a):把数组转成字符串
System.out.println("排序前:"+Arrays.toString(arr));
//public static void sort(int[] a):对数组进行升序排序
Arrays.sort(arr);
System.out.println("排序后:"+Arrays.toString(arr));
}
}
1.2.2Arrays类中构造方法的问题
Arrays类中真的没有构造方法吗?
一个类中没有构造方法,系统将提供一个无参构造方法。
而我们在帮助文档中没有看到Arrays类的构造方法,这是为什么呢?
通过查看源码,我们找到了如下的内容:
private Arrays() {}
Arrays类中有构造方法,只不过构造方法被private修饰,外界无法使用这个构造方法来创建对象。因为外界无法使用,所以帮助文档中就看不到。
构造方法被private修饰,外界无法使用这个构造方法来创建对象。
Arrays a = new Arrays();//报错The constructor Arrays() is not visible
Arrays类的这种设计是常用的工具类的设计思想:
构造方法私有。成员都用static修饰。
如 Math,Collections等
第2章包装类
2.1基本类型包装类的概述
package com.itheima_01;
/*
* 需求:我要判断一个数据是否在int范围内?
* 要想判断一个数据是否在int范围内,首先我们得知道int范围,在前面我们讲解基本数据类型的时候说过了:
* -2147483648 到 2147483647
*
* 为了对基本数据类型进行更多更方便的操作,Java就针对每一种基本数据类型提供了一个对应的引用类型。
* 基本类型包装类--基本数据类型
* Byte byte
* Short short
* Integer int
* Long long
* Float float
* Double double
* Character char
* Boolean boolean
*
* 基本数据类型包装类最常见的用法就是用于基本数据类型和字符串之间进行相互转换。
*/
public class IntegerDemo {
public static void main(String[] args) {
// public static final int MAX_VALUE//final修饰,表明是常量,static修饰表明可以直接用类名来访问
System.out.println(Integer.MAX_VALUE);
// public static final int MIN_VALUE
System.out.println(Integer.MIN_VALUE);
}
}
2.2Integer类的概述和构造方法
Integer:Integer类在对象中包装了一个基本类型 int 的值。它里面其实是一个int类型的值,只不过被他进行包装之后,就可以有成员变量和成员方法供我们使用。
构造方法:
Integer(int value)
Integer(String s)
注意:这个字符串必须由数字字符组成
2.2.1案例代码三
package javalearning_02;
/*
* Integer:Integer类在对象中包装了一个基本类型 int 的值。它里面其实是一个int类型的值,只不过被他进行包装之后,就可以有成员变量和成员方法供我们使用。
*
* 构造方法:
* Integer(int value)
* Integer(String s)
* 注意:这个字符串必须由数字字符组成
*/
public class IntegerDemo {
public static void main(String[] args) {
//Integer(int value)
int a = 100;
Integer i = new Integer(a);
System.out.println(i); //Intege类的100。直接println对象名默认调用的是该对象的toString()。这里输出100,说明重写了该方法
System.out.println("------------");
//Integer(String s)
String s = "100";
//String s = "abc";//报错NumberFormatException:数据格式化异常,因为Integer(String s)这个字符串必须由数字字符组成
Integer ii = new Integer(s);
System.out.println(ii);//Intege类的100
}
}
2.3int类型和String类型的相互转换
int类型和String类型的相互转换
int – String
使用String类中的public static String valueOf(int i)
String – int
使用Integer类中的public static int parseInt(String s)
2.3.1案例代码四
package javalearning_03;
/*
* int类型和String类型的相互转换
*
* int -- String
* 使用String类中的public static String valueOf(int i)
*
* String -- int
* 使用Integer类中的public static int parseInt(String s)
*/
public class IntegerDemo {
public static void main(String[] args) {
//int -- String
int number = 100;
//方式1
String s1 = "" + number;
System.out.println(s1);//字符串100,说明String类改写了toString方法,否则输出的是包名类名@地址值
//方式2
//public static String valueOf(int i)
String s2 = String.valueOf(number);//静态方法可以通过类名直接调用
System.out.println(s2);//100
System.out.println("--------------");
//String -- int
String s = "100";
//方式1
//String -- Integer -- int
Integer i = new Integer(s);
//public int intValue()
int x = i.intValue();
System.out.println(x);
//方式2
//public static int parseInt(String s)
int y = Integer.parseInt(s);
System.out.println(y);
}
}
2.4Integer的练习之把字符串中的数据排序
需求:
我有如下一个字符串:”91 27 46 38 50”
请写代码实现最终输出结果是:”27 38 46 50 91”
说到排序,想起数组排序,那元素应该在数组中,于是我们想把字符串中的数字放到一个数组中。
提示:这里需要参考String类中的方法:
public String[] split(String regex)
2.4.1案例代码五
package javalearning_04;
import java.util.Arrays;
/*
* 我有如下一个字符串:”91 27 46 38 50”
* 请写代码实现最终输出结果是:”27 38 46 50 91”
* 说到排序,想起数组排序,那元素应该在数组中,于是我们想把字符串中的数字放到一个数组中。
* 提示:这里需要参考String类中的方法
* public String[] split(String regex)
*
* 分析:
* A:定义一个字符串对象
* B:把字符串中的数字数据存储到一个int类型的数组中
* C:对int数组进行排序
* D:把排序后的数组中的元素进行拼接得到一个字符串
* E:输出字符串
*/
public class IntegerDemo {
public static void main(String[] args) {
//定义一个字符串对象
String s = "91 27 46 38 50";
//把字符串中的数字数据存储到一个int类型的数组中
//数组长度我不知道,也不方便数,于是去API的Sting类中看一下有没有什么方法可以帮我们
//public String[] split(String regex)
//根据给定正则表达式的匹配拆分此字符串。 返回一个字符串数组
//该方法的作用就像是使用给定的表达式和限制参数 0 来调用两参数 split 方法。因此,所得数组中不包括结尾空字符串。
/*
Regex 结果
: { "boo", "and", "foo" }
o { "b", "", ":and:f" }
*/
String[] strArray = s.split(" ");
/*
for(int x=0; x<strArray.length; x++) {
System.out.println(strArray[x]);
}
*/
//得到一个字符串数组,但我们想要的是int数组
//定义一个int类型的数组
int[] arr = new int[strArray.length];//字符串数组的长度是几,int数组的长度就是几
for(int x=0; x<arr.length; x++) {
arr[x] = Integer.parseInt(strArray[x]);//把字符串转化成int
}
//对int数组进行排序
Arrays.sort(arr);
//把排序后的数组中的元素进行拼接得到一个字符串
StringBuilder sb = new StringBuilder();
for(int x=0; x<arr.length; x++) {
if(x==arr.length-1) {
sb.append(arr[x]);
}else {
sb.append(arr[x]).append(" ");
}
}
String result = sb.toString();//把StringBuilder转成String
//输出字符串
System.out.println("result:"+result);
}
}
2.5JDK5的新特性自动装箱和拆箱
JDK5新特性:
自动装箱:把基本数据类型转换为对应的包装类类型
public static Integer valueOf(int i)
自动拆箱:把包装类类型转换为对应的基本数据类型
public int intValue()
Java程序的运行:
编写java文件 – 编译生成class文件 – 执行
注意:在使用包装类类型的新特性的时候,如果做操作,最好先判断是否为null。
开发中的原则:
只要是对象,在使用前就必须进行不为null的判断。
2.5.1案例代码六:
package javalearning_05;
/*
* JDK5新特性:
* 自动装箱:把基本数据类型转换为对应的包装类类型
* public static Integer valueOf(int i)
* 自动拆箱:把包装类类型转换为对应的基本数据类型
* public int intValue()
*
* Java程序的运行:
* 编写java文件 -- 编译生成class文件 -- 执行class文件
* class文件在bin文件夹里。当程序保存的那一刻就会编译生成class文件,编译生成class文件时就会进行一些自动装箱拆箱的动作。
* class文件的内容我们是看不懂的,所以要使用反编译工具来看class文件。
* 如XJad。将其打开并将class文件拖进去就可查看,并且会帮你生成一个对应的java文件,这就是反编译后的文件。
*
* 注意:在使用包装类类型的新特性的时候,如果做操作,最好先判断是否为null。
*
* 开发中的原则:
* 只要是对象,在使用前就必须进行不为null的判断。
*/
public class IntegerDemo {
public static void main(String[] args) {
//创建一个包装类类型的对象
//Integer i = new Integer(100);
Integer ii = 100; //自动装箱。可以直接这样,而不用像上面那行代码,比较麻烦
ii += 200; //ii = ii + 200;
//ii是包装类类型integer,200是基本类型int,不可以直接操作,
//于是自动拆箱将ii变为int型的100,再与200操作得300,然后自动装箱将int300变成包装类integer300
System.out.println(ii);//300
/*上面的三行代码通过反编译工具生成的以下三行代码
Integer ii = Integer.valueOf(100);//integer能直接调用valueof方法说明valueof是静态的。他能赋值给integer说明这个方法的返回值是integer类型的
//自动装箱实际上是通过这个方法首先的public static Integer valueOf(int i)
ii = Integer.valueOf(ii.intValue() + 200);public int intValue()以int类型返回该Integer的值
System.out.println(ii);
*/
/*
Integer iii = null;
iii += 300; //报错NullPointerException
//因为iii是null,在自动拆箱时,是null在调用intvalue方法,所以出现空指针异常
//所以在用包装类类型时向下面那样添加一个判断来确保不是null
System.out.println(iii);
*/
Integer iii = null;
if(iii != null) {
iii += 300;
System.out.println(iii);//这段代码并未运行因为iii时null
}
}
}
第3章Date类和SimpleDateFormat类
3.1Date类的概述和构造方法
Date:Date表示特定的瞬间,精确到毫秒。
构造方法:
Date():根据当前时间创建的日期对象
Date(long date):根据给定的毫秒值创建对象,从1970 年 1 月 1 日 00:00:00以来的毫秒数
3.1.1案例代码七:
package javalearning;
import java.util.Date;
/*
* Date:Date表示特定的瞬间,精确到毫秒。
*
* 构造方法:
* Date():根据当前时间创建的日期对象
* Date(long date):根据给定的毫秒值date创建对象,从1970 年 1 月 1 日 00:00:00
*/
public class DateDemo {
public static void main(String[] args) {
//Date()
Date d = new Date();
System.out.println(d);
//Date(long date)
long date = 1000 * 60 * 60;//1000毫秒*60是一分钟,*60是一小时
Date dd = new Date(date);
System.out.println(dd);//Thu Jan 01 09:00:00 CST 1970。因为我们是北京时间东八区,所以加了8小时,否则是01:00:00
}
}
3.2Date类的成员方法getTime()和setTime()
成员方法:
public long getTime():获取的是毫秒值。从1970年1月1日 00:00:00开始的。
public void setTime(long time):设置时间,给的是毫秒值。
从Date得到一个毫秒值:
getTime()
从一个毫秒值得到一个Date对象
无参构造方法加setTime(long time)
有参构造方法
3.2.1案例代码八:
package javalearning;
import java.util.Date;
/*
* public long getTime():获取的是毫秒值。从1970年1月1日 00:00:00开始的。
* public void setTime(long time):设置时间。注意这里的time给的是毫秒值。
*
* 从Date得到一个毫秒值:
* getTime()
*
* 给定毫秒值得到一个Date对象:
* 无参构造方法+setTime(long time)
* 带参构造方法
*/
public class DateDemo2 {
public static void main(String[] args) {
//创建对象
Date d = new Date();
//public long getTime()
System.out.println(d.getTime());//1648020129488
//public void setTime(long time)
d.setTime(1000*60*60);
System.out.println(d.getTime());//3600000
}
}
3.3SimpleDateFormat类的概述和使用
SimpleDateFormat:是一个以与语言环境有关的方式来格式化和解析日期的具体类。
它允许进行格式化(日期 -> 文本)、解析(文本 -> 日期)
格式化(日期 -> 文本): Date – String
public final String format(Date date)
解析(文本 -> 日期): String – Date
public Date parse(String source)
构造方法:
SimpleDateFormat()
用默认的模式和默认语言环境的日期格式符号构造 SimpleDateFormat。
SimpleDateFormat(String pattern)
用给定的模式和默认语言环境的日期格式符号构造 SimpleDateFormat。
3.3.1案例代码九:
package javalearning_01;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
/*
* SimpleDateFormat:是一个以与语言环境有关的方式来格式化和解析日期的具体类。
* 它允许进行格式化(日期 -> 文本)、解析(文本 -> 日期)
*
* 格式化(日期 -> 文本): Date -- String
* public final String format(Date date)
*
* 解析(文本 -> 日期): String -- Date
* public Date parse(String source)
*
*/
public class SimpleDateFormatDemo {
public static void main(String[] args) throws ParseException {
/*
//Date -- String
Date d = new Date();
//SimpleDateFormat(): 用默认的模式//22-2-5 下午15:30
//SimpleDateFormat sdf = new SimpleDateFormat();
//SimpleDateFormat(String pattern):用给定的模式
SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
String s = sdf.format(d);
//现在虽然实现了把日期格式化成一个字符串,但是不是我们想要的格式
//我们想要的格式是:xxxx年xx月xx日 xx:xx:xx
System.out.println(s);//2022年2月 5日15:30:58
*/
//String -- Date
String str = "2080-08-08 12:23:45";
//把一个字符串解析为日期的时候,请注意模式字符串和给定的日期字符串的格式要匹配
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date d = sdf.parse(str);//这个方法会抛一个异常,这里选择“Add throws declaration” 即可
System.out.println(d);//Thu Aug 08 12:23:45 CST 2080
}
}
3.4Date的练习之日期工具类的定义和使用
3.4.1制作工具类DateUtil
3.4.1.1案例代码十:
package javalearning;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
/*
* (回想Arrays)工具类的特点
*
* 构造方法私有
* 成员方法静态
*/
public class DateUtil {
private DateUtil() {}
/*
* 把日期转换为指定格式的字符串
* 两个明确:
* 返回值类型:String
* 参数列表:Date date, String format (日期和指定格式)
*/
public static String dateToString(Date date, String format) {
SimpleDateFormat sdf = new SimpleDateFormat(format);
String s = sdf.format(date);
return s;
}
/*
* 把指定格式的字符串解析为日期
* 两个明确:
* 返回值类型:Date
* 参数列表:String s, String format
*/
public static Date stringToDate(String s,String format) throws ParseException {
SimpleDateFormat sdf = new SimpleDateFormat(format);
Date d= sdf.parse(s);这个方法会抛一个异常,这里选择“Add throws declaration” 即可
return d;
}
}
3.4.2测试工具类
3.4.2.1案例代码十一:
package javalearning;
import java.text.ParseException;
import java.util.Date;
public class DateUtilTest {
public static void main(String[] args) throws ParseException {
Date d = new Date();
String s = DateUtil.dateToString(d, "yyyy年MM月dd日 HH:mm:ss");//静态方法可以用类名调用
System.out.println(s);
String s2 = DateUtil.dateToString(d, "yyyy年MM月dd日");
System.out.println(s2);
String s3 = DateUtil.dateToString(d, "HH:mm:ss");
System.out.println(s3);
String str = "2080-08-08 12:23:34";
Date dd = DateUtil.stringToDate(str, "yyyy-MM-dd HH:mm:ss");
System.out.println(dd);
}
}