API和IO流
1.API
大多数API都没有构造方法,当成员方法都是静态的,以便不用创建对象可以之间类名调用
1.1 Math
代码示例:
public class MathDemo {
public static void main(String[] args) {
System.out.println("max(5,9)="+Math.max(5,9));
System.out.println("min(5,9)="+Math.min(5,9));
System.out.println("pow(2,4)="+Math.pow(2,4));
System.out.println("abs(-8)="+Math.abs(-8));
System.out.println("ceil(5.1)="+Math.ceil(5.1));
System.out.println("floor(5.9)="+Math.floor(5.9));
System.out.println("round(5.3)="+Math.round(5.3));
System.out.println("random()是【0-1)的随机数"+Math.random());
}
}
运行结果:
max(5,9)=9
min(5,9)=5
pow(2,4)=16.0
abs(-8)=8
ceil(5.1)=6.0
floor(5.9)=5.0
round(5.3)=5
random()是【0-1)的随机数0.19905643174629506
1.2 System![在这里插入图片描述](https://img-blog.csdnimg.cn/85c09a1d573846548b11889e8a9f2c88.png#pic_center)
代码示例:
public class SystemDemo {
public static void main(String[] args) {
System.out.println("开始");
long start = System.currentTimeMillis();
System.out.println("此时距1970年毫秒值" + start);
for (int i = 0; i < 100; i++) {
System.out.print(" " + i);
}
System.out.println();
long end = System.currentTimeMillis();
System.out.println("运行完程序后距1970年毫秒值" + end);
System.out.println("程序运行了:"+(end-start)+"毫秒");
//让程序停止,无法输出结束
System.exit(1);
System.out.println("结束");
}
}
运行结果:
此时距1970年毫秒值1650849594216
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99
运行完程序后距1970年毫秒值1650849594217
程序运行了:1毫秒
1.3 Object
是所有类的根类
toString() | equals() |
---|---|
可以自动重写 | 可以自动重写 |
重写toString和equals
方式一:alt+inset
方式二:右键+generate
@Override
public boolean equals(Object o) {
//this s1
//o s2
if (this == o) return true;//如果地址相同,直接返回true
//如果o为空,或者o和this不在同一类中,返回false
if (o == null || getClass() != o.getClass()) return false;
Student student = (Student) o; //将o转换为Student对象
if (age != student.age) return false;
return name != null ? name.equals(student.name) : student.name == null;
}
1.4 冒泡排序
-
冒泡排序原理
- 一种排序的方式,对要进行排序的数据中相邻的数据进行两两比较,将较大的数据放在后面,依次对所有的数据进行操作,直至所有数据按要求完成排序
-
如果有n个数据进行排序,总共需要比较n-1次
-
每一次比较完毕,下一次的比较就会少一个数据参与
代码案例:
public class Demo {
public static void main(String[] args){
int[] arr = {12,59,8,555,78,3};
for (int i = arr.length; i >= 0; i--) {
for (int j = 0; j < i-1; j++) {
if(arr[j]>arr[j+1]){
int temp = arr[j];
arr[j]=arr[j+1];
arr[j+1]=temp;
}
}
}
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i]+" ");
}
}
}
运行结果:
3 8 12 59 78 555
1.5 Arrays
代码案例:
public class Demo {
public static void main(String[] args){
int[] arr = {12,59,8,555,78,3};
//排序
Arrays.sort(arr);
/*
public static String toString(int[] a) {
if (a == null)
return "null";
int iMax = a.length - 1;
if (iMax == -1)
return "[]";
StringBuilder b = new StringBuilder();
b.append('[');
for (int i = 0; ; i++) {
b.append(a[i]);
if (i == iMax)
return b.append(']').toString();
b.append(", ");
}
}
*/
System.out.println(Arrays.toString(arr));
}
}
运行结果:
[3, 8, 12, 59, 78, 555]
1.6 包装类
将数据包装成对象里,可以完成更多对数据的操作,常用的操作是字符串和数据之前的转换。
1.Integer类
valueOf()方法,可以传int或String,然后返回Inteder类型对象
代码案例:
public class Demo {
public static void main(String[] args) {
Integer i = new Integer(100);
System.out.println(i+" "+i.getClass());
System.out.println(i+" "+Integer.valueOf("100").getClass());
}
}
运行结果:
100 class java.lang.Integer
100 class java.lang.Integer
2.int与String之间的转换
int->String:可以直接进行“拼接”,即在int后加“”即可;还可以调用String的valueOf方法
String->int:可以int->Integer->String; 还可以调用Integer的parseInt方法
代码案例:
public class Demo {
public static void main(String[] args) {
System.out.println("int->String");
int a = 100;
String s = a + "";
//方式一
Integer i = new Integer(a);
System.out.println(s+" "+s.getClass());
System.out.println("-----------------------------");
//方式二
String s1 = String.valueOf(a);
System.out.println(s1 +" "+s1.getClass());
System.out.println("******************************");
System.out.println("String->int");
//方式一
String x1 = "100";
System.out.println(Integer.parseInt(x1));
System.out.println("-----------------------------");
//方式二
int ii = Integer.valueOf(x1).intValue();
System.out.println(ii);
}
}
运行结果:
int->String
100 class java.lang.String
-----------------------------
100 class java.lang.String
******************************
String->int
100
-----------------------------
100
3.字符串数据排序案例
public class Demo {
public static void main(String[] args){
String arr = "45 19 78 55 99 21 5";
String[] s = arr.split(" ");
int[] nu = new int[s.length];
for (int i = 0; i < s.length; i++) {
nu[i] = Integer.parseInt(s[i]);
}
Arrays.sort(nu);
StringBuilder sb = new StringBuilder();
for (int i = 0; i < s.length; i++) {
if(i==s.length-1){
sb.append(nu[i]);
}else{
sb.append(nu[i]).append(" ");
}
}
String s1 = sb.toString();
System.out.println(s1);
}
}
5 19 21 45 55 78 99
个人错误:
public class Demo {
public static void main(String[] args){
String arr = "45 19 78 55 99 21 5";
String[] s = arr.split(" ");
//错把s.length写成arr.length(),导致最开始程序不断报错,应该是越界了
System.out.println(arr.length());
System.out.println(s.length);
}
}
结果:
19
7
4.自动拆箱和自动装箱
自动装箱:
把基本数据类型转换为对应的包装类类型
自动拆箱:
把包装类类型转换为对应的基本数据类型
Integer i = 100; // 自动装箱
i += 200; // i = i + 200; i + 200 自动拆箱;i = i + 200; 是自动装箱
1.7 时间日期类
1.Date类
代码案例:
public class DemoDate {
public static void main(String[] args) {
//返回此时时间
Date d1 = new Date();
System.out.println(d1);
//在基准时间上加一小时,Date里的单位为毫秒
Date d2 = new Date(1000*60*60);
System.out.println(d2);
}
}
运行结果:
Thu Apr 28 20:53:32 CST 2022
Thu Jan 01 09:00:00 CST 1970
基准时间是1970-1-1 00:00:00 之所以是上面的结果是因为我们在东八区,需要在原基础上加8小时
代码案例:
public class DemoDate {
public static void main(String[] args) {
//返回基准时间距离现在有多少毫秒,采用计算间隔年份验证
Date d1 = new Date();
System.out.println(2022 - 1970);
System.out.println(d1.getTime() / 1000 / 60 / 60 / 24 / 365);
//结果和预想的不一样,是因为传入的 1000 * 60 * 60 * 24 * 365 的数值
//超过long范围,然后结果改变了
d1.setTime(1000 * 60 * 60 * 24 * 365);
System.out.println(d1);
long i = System.currentTimeMillis();
d1.setTime(i);
System.out.println(d1);
}
}
运行结果:
52
52
Sun Jan 18 08:40:28 CST 1970
Thu Apr 28 22:11:54 CST 2022
2.SimpleDateFormat类
重点用于日期的格式化和解析
代码案例:
public class DemoDate {
public static void main(String[] args) throws ParseException {
//默认格式
SimpleDateFormat sdf = new SimpleDateFormat();
//自定义格式
SimpleDateFormat sdf1 = new SimpleDateFormat("YYYY-MM-DD hh:mm:ss");
//Date->String
Date d = new Date();
//默认格式
String format1 = sdf.format(d);
System.out.println("默认格式:"+format1);
//自定义格式
String format = sdf1.format(d);
System.out.println("自定义格式:"+format);
//String->Date
String s = "1988-6-9 13:20:55";
Date parse = sdf1.parse(s);
System.out.println(parse);
}
}
运行结果:
默认格式:22-4-28 下午11:08
自定义格式:2022-04-118 11:08:03
Sun Dec 27 13:20:55 CST 1987
3.日期工具类案例
代码案例:
工具类:
public class DateUtils {
public static String dateToString(Date date,String format){
SimpleDateFormat sdf = new SimpleDateFormat(format);
return sdf.format(date);
}
public static Date stringToDate(String s,String format) throws ParseException {
SimpleDateFormat sdf = new SimpleDateFormat(format);
return sdf.parse(s);
}
}
测试类:
public class Demo {
public static void main(String[] args) throws ParseException {
Date date = new Date();
String s = "1988-8-6 15:54:21";
String format = "YYYY-MM-DD hh:mm:ss";
String s1 = DateUtils.dateToString(date, format);
System.out.println(s1);
Date date1 = DateUtils.stringToDate(s, format);
System.out.println(date1);
}
}
运行结果:
2022-04-118 11:45:07
Sun Dec 27 15:54:21 CST 1987
4.Calendar类
Calender类不是new出对象,而是getInsteance()方法来获取对象
Calender提供了一些操作日历字段的方法
Calender常用方法:
代码案例:
public class CalenderDemo {
public static void main(String[] args) {
//获取对象,getInstance()自动用当前时间初始化
//里面有从子类/孙类创建对象,是多态的形式
Calendar c = Calendar.getInstance();
//获取对应的日历字段
CalenderDemo.getCalenderToString(c);
System.out.println("--------------------------------------");
c.add(Calendar.YEAR,18);
c.add(Calendar.MONTH,6);
c.add(Calendar.DATE,-22);
CalenderDemo.getCalenderToString(c);
System.out.println("--------------------------------------");
c.set(2050,9,1);
CalenderDemo.getCalenderToString(c);
}
public static void getCalenderToString(Calendar c){
int year = c.get(Calendar.YEAR);
int month = c.get(Calendar.MONTH)+1;
int date = c.get(Calendar.DATE);
System.out.println(year + "年" + month + "月" + date + "日");
}
}
运行结果:
2022年4月29日
--------------------------------------
2040年10月7日
--------------------------------------
2050年10月1日
5.二月天案例
案例思路:
要获取二月有多少天,只需要得到二月的最后一天的date,采用三月一号减一天得到二月最后一天
代码:
public class Demo {
public static void main(String[] args) {
//创建日历对象
Calendar c = Calendar.getInstance();
Scanner sc = new Scanner(System.in);
System.out.println("请输入年份:");
int year = sc.nextInt();
c.set(year,2,1);
c.add(Calendar.DATE,-1);
int date = c.get(Calendar.DATE);
System.out.println(year+"年的二月有:"+date+"天");
}
}
运行结果:
请输入年份:
2000
2000年的二月有:29天
2.IO流
1.File类
运行前目录:
运行后目录:
之所以java.txt是文件夹而不是文本文档是因为用的mkdirs只能创建文件夹
代码案例:
public class Demo {
public static void main(String[] args) throws IOException {
//直接赋值目录参数
File f1 = new File("D:\\text\\java.txt");
//赋值根目录和子目录
File f2 = new File("D:\\text","java");
//用File对象加子目录创建对象
File f3 = new File("D:\\text");
File f4 = new File(f3,"javaSE\\java\\java.txt");
//如果没有java.txt文件就创建一个并且返回true,否则返回false
System.out.println(f1.createNewFile());
System.out.println("--------------------");
//创建单层目录
System.out.println(f2.mkdir());
//创建多层目录
System.out.println(f4.mkdirs());
}
运行结果:
true
--------------------
true
true
2.File常用方法
代码案例:
public class FileDemo {
public static void main(String[] args) throws IOException {
File f = new File("D:\\text\\java\\javaSE");
File f1 = new File(f,"java.txt");
f.mkdirs();
f1.createNewFile();
System.out.println("测试File是否是目录:"+f.isDirectory());
System.out.println("测试File是否是文件:"+f.isFile());
System.out.println("此抽象路径名是否存在"+f.exists());
//返回绝对路径字符串
System.out.println(f1.getAbsolutePath());
//将次抽象路径名转换为路径字符串,相对于上面的方法,下面得到的是File创建对象里赋值的字符串
System.out.println(f1.getPath());
System.out.println("********");
//返回此抽象路径名表示的目录或文件名称
System.out.println(f1.getName());
//返回此抽象路径名表示的目录或文件名称的字符串数组
String[] list = new File("D:\\text").list();
for (String s : list) {
System.out.println(s);
}
System.out.println("********");
//返回此抽象路径名表示的目录或文件名称的File串数组
File[] files = new File("D:\\text").listFiles();
for (File file : files) {
System.out.println(file);
}
}
}
运行结果:
测试File是否是目录:true
测试File是否是文件:false
此抽象路径名是否存在true
D:\text\java\javaSE\java.txt
D:\text\java\javaSE\java.txt
********
java.txt
java
java.txt
javaSE
********
D:\text\java
D:\text\java.txt
D:\text\javaSE
文件删除案例:
public class Demo {
public static void main(String[] args) throws IOException {
File f = new File("wysj01\\src\\com\\wy\\text04\\text.txt");
//在当前目录下创建文件
System.out.println(f.createNewFile());
System.out.println(f.delete());
//在当前目录下创建目录
File f1 = new File("wysj01\\src\\com\\wy\\text04\\text");
System.out.println(f1.mkdir());
System.out.println(f1.delete());
}
}
运行结果:
true
true
true
true
注意:如果要删除的文件或目录下还有内容,则无法删除成功,需要先将内容删除完才可以
3.递归
递归:从编程角度看就是方法调用自身的现象
优点:1)把一个复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解
2)递归策略只需少量的程序就可描述出解题过程所需要的多次重复计算;递归是与原问题相似的较小问题
注意:递归必须要有出口,否则递归太深,
递归求阶乘代码案例:
public class Demo {
public static void main(String[] args) throws IOException {
Scanner sc = new Scanner(System.in);
System.out.print("请输入一个数:");
int n = sc.nextInt();
System.out.println(n+"的阶乘为:"+f(n));
}
public static long f(int n){
if(n==1) {
return 1;
} else {
return n*f(n-1);
}
}
}
运行结果:
请输入一个数:5
5的阶乘为:120
递归得到文件绝对路径代码案例:
public class Demo {
public static void main(String[] args) {
File f = new File("D:\\text");
getAllDirectoryPath(f);
}
public static void getAllDirectoryPath(File f) {
File[] files = f.listFiles();
//遍历最好加上这句,增强代码的健壮性
if (files != null) {
//遍历File【】,对每个元素进行操作
for (File file : files) {
//判断是目录就继续调用,不是就输出绝对路径
if (file.isDirectory()) {
//继续调用
getAllDirectoryPath(file);
} else {
//输出绝对路径
String absolutePath = file.getAbsolutePath();
System.out.println(absolutePath);
}
}
}
}
}
运行结果:
D:\text\java\javaSE\java.txt
D:\text\java.txt
D:\text\javaSE\java\1.txt
D:\text\javaSE\java\java.txt\2.txt
4.IO流概述和分类
1.概述
- IO:输入/输出(Input/Output)
- 流:是一种抽象概念,是对数据传输的总称。也就是说数据在设备间的传输称为流,流的本质是数据传
输 - IO流就是用来处理设备间数据传输问题的。常见的应用:文件复制;文件上传;文件下载
按照数据的流向
输入流:读数据
输出流:写数据
按照数据类型来分
- 字节流
字节输入流
字节输出流- 字符流
字符输入流
字符输出流
IO流的使用场景
如果操作的是纯文本文件,优先使用字符流
如果操作的是图片、视频、音频等二进制文件。优先使用字节流
如果不确定文件类型,优先使用字节流。字节流是万能的流
5.字节流写数据
-
字节流抽象基类
- InputStream:这个抽象类是表示字节输入流的所有类的超类
- OutputStream:这个抽象类是表示字节输出流的所有类的超类
- 子类名特点:子类名称都是以其父类名作为子类名的后缀
-
字节输出流
- FileOutputStream(String name):创建文件输出流以指定的名称写入文件
-
使用字节输出流写数据的步骤
-
创建字节输出流对象(调用系统功能创建了文件,创建字节输出流对象,让字节输出流对象指向文件)
-
调用字节输出流对象的写数据方法write()
-
释放资源(关闭此文件输出流并释放与此流相关联的任何系统资源)
-
6.字节流复制图片
代码案例:
public class IODemo {
public static void main(String[] args) throws IOException {
//创建输入输出流对象
FileInputStream fis = new FileInputStream("D:\\text\\1.png");
FileOutputStream fos = new FileOutputStream("wysj01\\1.png");
//进行文本复制操作
byte[] bytes = new byte[1024];
int len;
while((len=fis.read(bytes))!=-1){
fos.write(bytes,0,len);
}
//后打开的先关闭
fos.close();
fis.close();
}
}
运行结果截图:
图片复制成功
6.字节流复制视频
代码案例:
public class Demo {
public static FileInputStream fis;
static {
try {
fis = new FileInputStream("D:\\text\\2.mp4");
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
public static FileOutputStream fos;
static {
try {
fos = new FileOutputStream("wysj01\\2.mp4");
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
public static BufferedInputStream bis = new BufferedInputStream(fis);
public static BufferedOutputStream bos = new BufferedOutputStream(fos);
public Demo() throws FileNotFoundException {
}
public static void main(String[] args) throws IOException {
long startTime = System.currentTimeMillis();
method1(fis,fos); //耗时:-3697毫秒
// method2(fis,fos); //耗时:-5毫秒
// method3(bis, bos); //耗时:-33毫秒
// method4(bis,bos); //耗时:-3毫秒
bos.close();
bis.close();
fos.close();
fis.close();
long endTime = System.currentTimeMillis();
System.out.println("耗时:" + (startTime - endTime) + "毫秒");
}
//基本字节流一次读写一个字节
public static void method1(FileInputStream fis, FileOutputStream fos) throws IOException {
int by;
while ((by = fis.read()) != -1) {
fos.write(by);
}
}
//基本字节流一次读写一个字节数组
public static void method2(FileInputStream fis, FileOutputStream fos) throws IOException {
byte[] bys = new byte[1024];
int len;
while ((len = fis.read(bys)) != -1) {
fos.write(bys, 0, len);
}
}
//字节缓冲流一次读写一个字节
public static void method3(BufferedInputStream bis, BufferedOutputStream bos) throws IOException {
int by;
while ((by = bis.read()) != -1) {
bos.write(by);
}
}
//字节缓冲流一次读写一个字节数组
public static void method4(BufferedInputStream bis, BufferedOutputStream bos) throws IOException {
byte[] bys = new byte[1024];
int len;
while ((len = bis.read(bys)) != -1) {
bos.write(bys, 0, len);
}
}
}
复制结果图片: