大家好,欢迎来到IT知识分享网。
一、Java基础信息
程序(application):一组有序的指令集合
指令:就是命令的意思
java的组成:javase/j2se(java标准版),javaee/j2ee(java企业版)(13几种技术)
java的应用:internet程序(b/s)和桌面应用程序(c/s) browser
什么是java:是一种面向对象的高级编程语言
安装jdk ,下载,8
配置jdk:选中计算机右键属性->高级系统设置->环境变量->系统变量的path里配置jdk路径
验证jdk是否配置成功 开始->cmd->java -version
记事本开发程序的步骤
①编写:编写源文件Test.java 编译javac Test.java
②编译:字节码Test.class 运行java Test
③运行:运行结果
1.1java的基本结构信息
public class Test{
public static void main(String[] args){
System.out.println(“你好”);
}
}
public 公共的class 类static 静态void 无返回值main 主要的String 字符串System 系统out 输出print 打印
注意四点:
①类名的首字母要大写,要保证类名与文件名一样
②所有的括号要成对出现,遇到大括号的开始要缩进,大括号的结束要与其对应大括号的开始最前端对齐
③所有标点符号都是英文的
④每行只能放一句代码,每句以分号结束
打印:
System.out.print(); 只打印
System.out.println(); 打印+换行
转义\:反斜杠必须双引号
\t制表位
\n换行
注释:
单行注释 ://注释内容 添加和取消:ctrl+/
段落注释:/*注释内容*/ 添加:ctrl+shift+/ 取消:ctrl+shift+/
1.2数据类型、变量、运算符
数据类型、变量、运算符、类型转化 Scanner
标识符:凡是人为可以起名字的地方
java关键字:java自用的单词代表某种意义,所有 关键字都是小写的
1.2.1数据类型:
①整型 int:不带小数点的 数字,例如 5,15,20 ,-1都是整型数据
byte 1、short 2、int 4、long 8
②浮点型 double:带小数点的 数字:例如5.0,10.2,100.1 都是浮点型数据
③字符串型 String:双引号引起来的 0,1或多个任意字符 例如 “”,”我”,”☆abc@!我” 都是字符串数据
④字符型 char:单引号引起来的 单个任意字符, 例如:’a’,’1′,’@’,’我’,’☆’
⑤布尔型 boolean:描述现实中的两种的东西,他的值只有两个 true,false
1.2.2变量:
就是模拟现实中的容器,用来存取数据
变量的三要素:
变量名,变量类型,变量值
定义变量:int a = 10;
变量的三步走:
①声明变量:数据类型 变量名; 例如 int a;String s;char c;boolean b;double d; 造容器的意思
②赋值:变量名=数据; 例如: a =5;s=”你好”; 装东西的意思
③取值(使用):System.out.println(变量名);例如 int b; b = a 取东西的意思
变量的命名规则(标识符):
①变量名只能有四部分组成(字母,数字,下划线_,美元符号$)任意组成,但数字不能开头
②不能与java关键字重名
③见名知意(语义化,在实际开发中有助于维护)
④驼峰标志(小驼峰:第一个单词小写,剩下接着的首字母大写)
注:声明两个同名变量导致编译错误
1.2.3运算符:
①赋值运算符 =
- 后面的给前面,后面的复制一份给前面
- 前面如果有值,扔掉,接受后面的值
②算术运算符:整型跟整型运算最终结果是整型,取整数部分
+ 加 – 减 * 乘 / 除
% 求余,求模,取余,取模
③关系运算符:最终结果是boolean
> < >= <= == !=
④逻辑运算符:两个只能放boolean类型
⑤一元运算符:两边只能跟数字变量
++ —
在前:先自+/-,再赋值计算
在后:先赋值计算,再自+/-
(注意:每次自增自减1。一元运算符在变量之后,先做别的运算,再将自身值+1,运算符在变量之前,先自身值+1,再其他运算)
三元运算符 这里不提
小括号()最高
赋值= 最低
1.2.4类型转换 :
注意点:①任何数据类型跟字符串相加往字符串去转
3.小转大为自动转换(大包含小的类型)
4.大转小为强制转换(大的类型比小大类型存在多余的部分)
②如果一个操作数为double型,则整个表达式可提升为double型
③默认是自动转换
强制转换:数值类型(整型和浮点型)互相兼容
(类型名)表达式
int a = (int)5.5;
目标类型<源类型(大转小)强转
自动转换:
double d = 5;//前有隐形的int
目标类型>源类型(小转大)自转
1.2.5Scanner(扫描仪):
代码阻塞,获取用户的输入,和输出打印语句长连用
Scanner in = new Scanner(System.in);
in.next();//不能得到带有空格的字符串
in.nextInt();// 接收整数
in.nextDouble();//接受多浮点型(双精度)
in.nextBoolean();//接受布尔型
in.nextFloat();// 接收小数(单精度)
in.nextLine();//可以获得空白
in.next();//不能得到带有空格的字符串
①random随机数
Random r = new Random();
r.nextInt(3);
Math.random() 范围 :[0.0,1.0)
(max+1-min)*Math.random()+min
②hasNextInt()
处理系统异常
2.循环
2.1单支结构:if
2.2双支结构if-else
多支:if-else if…..-else(范围小的写上面)
2.3switch选择结构
switch选择结构适用于条件判断是等值判断的情况
2.4while循环
③.equals()
方法用于判断 Number 对象与方法的参数进是否相等。
④为什么需要程序调试?
在编写程序过程中有时也出现错误,但不好发现和定位错误,
通过代码阅读或者加输出语句查找程序错误
当程序结构越来越复杂时,需要专门的技术来发现和定位错误,就是“程序调试”
1、程序调试的目的?
找出缺陷原因,修正缺陷
2、程序调试的主要方法?
设置断点、单步执行、观察变量
2.5do…..while
2.6for循环
⑤break:改变程序控制流
用于do-while、while、for中时,可跳出循环而执行循环后面的语句
⑥continue:只能用在循环里
跳过循环体中剩余的语句而执行下一次循环
break语句终止某个循环,程序跳转到循环块外的下一条语句
continue跳出本次循环,进入下一次循环
二、进阶版Java
1.面向对象oop(object orientend programming)
(面试题)1.0对象创建流程:p对象(p引用指向的这个对象)
流程步骤:堆里放着的是对象
栈里的p就是对象的引用/对象名(好比一个人有多个名字,栈—代名词)
Person p = new Person(“小倩”,20);:
第一步:先在方法区加载Person类
第二步:new: 先在 堆 里面开辟带有地址的一个空间
第三步:先对属性默认初始化 看Person类里有几个属性(age 0,name null)
然后显示的初始化,Person类里有对age赋值(age 90,name null)引用数据类型不能直接存放在栈中,基本数据类型可以。
第四步:Person(“小倩”,20) 对构造器(对 对象的初始化,而不是创建对象)进行处理
①把构造器里的形参与实参对应,把小倩给n,最后给name属性。
此时,在方法区的常量池里开辟一个空间有一个地址,小倩就放在这里。
与此同时堆里面对应的 属性地址 里的name属性 的属性值 就有一个对应的地址,此时这个地址就指向它。
就把name的null 换成小倩了。
同比:
把20传给a,a赋给age,此时age就换成了20。
第五步:new Person(“小倩”,20)加载完成后
在栈里开辟空间时 空间里放着p
把堆里的地址返回给p,p就是对象的引用
p就指向了堆里的对应的空间
⑦this关键字
指的是当前对象
this.类成员(成员变量和成员方法) 可以用在所有方法内
this(参数):他的意思调用本类的构造器,只能用在构造器里的第一行
如果本类没有指的是上一级,依次类推,知道object类。
⑧static关键字
静态的不能访问非静态的,非静态的可以调用静态的
同一时刻,该类的所有对象中该变量值都相同
static静态的 只能修饰类成员,一但修饰了类成员,类成员属于类,不属于对象
⑨super()
super 给编程带来的便利/细节 :
查找属性和下面的的查找方法一样的规则:
super 和 this 的比较 :
⑩final关键字
修饰类:类不能被继承
修饰方法:方法不能被重写
修饰变量:变量不能被重新赋值
具有安全机制。
1.1封装encaspulation
字面意思:定义私有的属性,用公共的方法去访问
真正意思:隐藏细节,对外提供接口
1.2构造器construtor
构造器是对 对象的初始化 而不是创建对象
快捷键:fn+alt+insert
方法名和类名一样,没有返回类型 public 类名(){}
特点:
①你写不写都有一个默认构造器,一但添加了带参的构造器,默认的消失
②先执行父类的构造器,再执行子类的构造器
作用:起到初始化的作用,创建对象调用
无参构造
有参构造
this可有可无,默认就是当前的
1.3继承
B继承A,A拥有B的所有(除私有和构造器)
继承条件:满足B是A的说法,B继承A。 不能滥用继承,子类和父类之间必须满足 is-a 的逻辑关系
特点:
①单根性:一个类只能有一个父类。 子类最多只能继承一个父类(指直接继承),即 java 中是单继承机制。 思考:如何让 A 类继承 B 类和 C 类? 【A 继承 B, B 继承 C】
②传递性:子类拥有 父类的非私有的类成员(成员变量和成员方法),私有的类成员可以通过父类提供的公共的方法去访问。
③默认情况下都会先调用父类的构造器,一直到所调用的当前的构造器。子类必须调用父类的构造器, 完成父类的初始 。( 父类构造器的调用不限于直接父类!将一直往上追溯直到 Object 类(顶级父类) 。 java 所有类都是 Object 类的子类, Object 是所有类的基类)
④ 当创建子类对象时,不管使用子类的哪个构造器,默认情况下总会去调用父类的无参构造器。【如果父类无参构造器被有参构造器覆盖了,则必须在子类的构造器中用 super(属性值…); 去指定使用父类的哪个构造器,完成对父类的初始化工作,否则,不会通过 。】
⑤如果希望指定去调用父类的某个构造器,则显式的调用一下 : super(对应的实参);
⑥ super() 和 this() 都只能放在构造器第一行,因此这两个方法不能共存在一个构造器
语法:public class B extends A{}
子类创建的内存布局:
栈:main方法,开辟Son空间
堆:引用数据类型的属性、基本数据类型的属性和属性值。地址给栈中的main方法。
方法区:
常量池:堆里面 引用数据类型的属性值。地址给堆中的属性。
类之间的继承关系
访问修饰符
public都有访问权限(本类、不同类同包、不同包继承、不同包不继承)
private只有本类有,别的都不能
练习题:
在Computer父类中设置了带参的构造器,无参的构造器被覆盖了,无默认的无参构造器。此时PC子类的构造器默认继承了Computer的无参构造器,就会报错
解决:创建一个子类的带参构造器,fn+alt+insert,这里IDEA根据继承的规则,自动把构造器的调用写好了
(体现了继承设计的基本思想,父类的构造器完成父类属性初始化,子类的构造器完成子类属性的初始化)
继承机制起到一个支撑的作用:
1.4重载overload
方法重载好处:一个方法名可以搞定好多功能, 减轻了起名、 记名 的麻烦
现实中:同一个对象对同一行为,传的内容不一样结果不一样
代码中:
在同一类中,方法名:要相同
形参列表:不相同(形参/数据 类型、个数、顺序 至少有一个不一样)
返回类型:无要求
1.5可变参数
java 允许将同一个类中多个同名同功能但参数个数不同的方法,封装成一个方法。 就可以通过可变参数实现
语法: 访问修饰符 返回类型 方法名(数据类型… 形参名) { }
1.7作用域
1.6重写override
2.子类书写过程中要一直遵循是父类的子类的规则,否则会报错
3.子类方法没办法修改父类的访问权限
重写的使用,子类中的方法和父类中的方法重写,子类方法调用时直接借助super.方法,再加上自己单独的属性就书写完成了
1.7多态polymorphic
方法或对象具有多种形态。是面向对象的第三大特征,多态是建立在封装和继承基础之上的。
多态的体现:
1)方法的多态:重写和重载就是体现多态
2) 对象的多态 (核心,困难,重点)
现实中多态:同一类型不同类型的对象对同一行为表现结果不同(切:厨师,医生,导演 都是人)
代码中多态:有继承,有重写,有父类类型的变量指向子类对象
编译类型是(机器语言)编译器看到的类型,运行类型是java真正执行的时候运行的一个类型。
属性看编译类型,方法看运行类型
多态的前提是:两个对象(类)存在继承关系
多态的向上转型
多态向下转(强转)
不可以,上面指向的是Cat
只有指向Dog,这里才可以强转
instanceOf 比较操作符,用于判断对象的运行类型是否为 XX 类型或 XX 类型的子类型
1.8动态绑定机制(非常重要)
调用对象方法时,该方法会和该对象的运行类型绑定
属性 没有动态绑定机制,就近原则使用
1.9API方法
1.字符串String方法
String StringBuffer StringBuilder 三个都可以操作字符串。
String底层不可以,每次变化都会生成一个新的字符串对象。安全的。
StringBuffer和StringBuilder它字符串可以变,每次变化不会生成新的空间。
StringBuffer它是线程安全的,因为它加了同步锁。而StringBuilder它是线程不安全。效率高。
一般我们使用StringBuffer就可以
str.length() 获取长度
insert(i,’,’)(参数1:第几位下标,参数2:’用什么分割’)
|
str.charAt(1) |
返回下标所在的字符(参数为int,返回char) |
|
str.concat(“呵呵”) |
追加字符(参数为string,返回string) |
|
str.equals(str1) |
是String的Object方法,也比较地址(内容一样统统equals())。看是否是重写,重写的话比较的是内容,没有重写比较的是地址和内容和”==”一样的意思。 ==比较看是否是一个对象,值是否相等 基本数据类型判断:值是否相等 引用数据类型:要看地址和值 |
|
str.indexOf(“1”) str.indexOf(“1”,2) |
返回索引值,查找字符串所在的下标(有一个参数时就是要查找的字符) 从第几个索引位置开始,查找字符(参数一:要查找的字符,参数二:第几个下标开始) |
|
str.lastIndexOf(“1”) str.lastIndexOf(“1”,2) |
从后查找,下标还是从0(前)开始 (参数一:要查找的字符,参数二:第几个下标开始) |
|
str.substring(1,3) |
截取字符(参数1:从下标几开始,参数2:到下标几结束) |
|
str.compareTo(str1) |
一样返回0 大返回正的数 小返回负的数 |
|
str2.split(“,”) |
返回值为String,根据匹配给定的正则表达式来拆分字符串。 |
|
str.length() |
返回值为int,字符串长度 |
|
str.trim() |
用于删除字符串的 头尾 空白符。 |
|
str.isEmpty() |
返回boolean类型:true/false。判断字符串是否为空。 |
|
contains() |
判断字符串中是否包含指定的字符或字符串 |
|
replace() |
通过用 newChar 字符替换字符串中出现的所有 searchChar 字符,并返回替换后的新字符串。 |
|
toUpperCase() |
将小写字符转换为大写。返回转换后字符的大写形式,如果有的话;否则返回字符本身。 |
|
toLowerCase() |
将大字符转换为小写。返回转换后字符的小写形式,如果有的话;否则返回字符本身。 |
|
“abc123”.toCharArray() |
将字符串转换为字符数组。 |
|
Str1.equalsIgnoreCase( Str4 ) |
将字符串与指定的对象比较,不考虑大小写。 |
|
reverse() |
反转 |
|
delete(1,6) |
删除指定位置的字符 |
|
append(“”) |
追加 |
2.Integer和Charater类
public class Test { public static void main(String[] args) { //把整数字符串转化为基本类型 String str="123"; int i = Integer.parseInt(str); System.out.println(i); //把包装类转化为基本类型 Integer a=new Integer(15); int i1 = a.intValue(); Integer a1 = 128; Integer a2 = 128; System.out.println(a1==a2); //true //==引用类型比较--引用地址的比较. Integer它的值超过127它就会创建新的地址。 //如果没有超过127等价于基本类型 System.out.println(a1.equals(a2));//比较的值 } }
static boolean isDigit(char ch) : 判断指定的字符是否为数字。 static boolean isLetter(char ch) :判断指定的字符是否为字母 static boolean isLowerCase(char ch) :判断指定的字符是否为小写字母 static boolean isUpperCase(char ch) :判断指定的字符是否为大写。
3.Arrays数组工具类
|
sort |
排序 |
|
|
copyof(数组,newLength) |
复制并扩容 |
|
|
binarySearch() |
二分查找 |
|
|
fill |
填充 |
|
4.Object类
Student s1=new Student(“秦桂祥2”,16);
Student s2=new Student(“秦桂祥”,18);
|
equals() |
//equals方法 System.out.println(s1==s2);//false System.out.println(s1.equals(s2));//false.Object类中equals方法本地比较的还是两个对象的引用地址。 //如果想比较两个对象的内容,则需要重写Object类中equals方法。 //因为字符串类重写了equals |
|
|
toString() |
System.out.println(s1);//调用的toString方法。 System.out.println(s1.toString());//调用的toString方法。默认来自Object类。如果打印对象想显示自己的属性信息可以重写toString |
|
|
hasCode() |
System.out.println(s1); System.out.println(s2); System.out.println(s1==s2);//两个对象的hashcode相同,他们一定是同一个对象 //两个对象的hashcode相同,equals一定相同吗 |
|
(面试题)equals和==
==:它可以比较基本类型和引用类型。比较基本类型比较的是值,而比较引用类型比较的引用地址。
equals: 它只能比较引用类型。如果没有重写Object类中的equals方法它比较的还是引用地址。如果想比较值则需要重写equals。
1.10接口interface
接口是一个特殊的抽象类
特殊:接口中所有的方法都是抽象方法,而且接口中所有的属性都是静态常量。而且接口弥补了抽象类的单继承的缺点。—干爹
个人理解:接口就是指定一个规范,类来实现它,方便管理。
语法: publice interface 接口名{ //静态常量属性 //抽象方法 } public interface Usb { //完整形式 public static final double width=12; public abstract void useUsb(); public abstract void show(); //修饰符可省略 public interface Usb { double width=12;//默认修饰符也是public static final void useUsb(); //默认public abstract void show(); } }
接口和抽象类一样也是无法创建类对象。 需要让其他类来实现该接口。类在实现接口时需要把接口中所有的抽象方法重写。
//语法 public class 类名 implements 接口名,接口名....{ }
interface A{ void a(); } interface B{ void b(); } //接口可以继承多个接口。同类型使用继承关系。 interface C extends B,A{ void c(); } class F implements C{ @Override public void a() { } @Override public void b() { } @Override public void c() { } }
public class 类名 extends 父类 implements 接口1,接口2...{ }
(面试题)2.0接口和抽象类区别
1.相同:接口和抽象类都无法创建对象,他们都是用于父亲和多态的体现。
2.不同:抽象类有构造方法,接口没有。
抽象类中可以没有抽象方法,而接口中都是抽象方法。JDK1.8以前
抽象类中可以有普通属性,接口中所有的属性都是静态常量。
一个类只能继承一个抽象类,但是却可以实现多个接口。
2.1包装类
万事万物皆为对象,基本类型。为了满足这种需求,为基本数据类型提供了包装类。类中会包含想要的功能方法。有这些方法我就可以对基本类型进行操作了。”123″–>整型123.
int–>Integer
byte–>Byte
short–>Short
long–>Long
double—>Double
float—>Float
boolean–>Boolean
char—>Character
自动装箱
装箱:把基本数据类型转化为包装类的过程
public class Test { public static void main(String[] args) { int a=15;//基本类型 Integer b=a;//自动装箱 必须保证1.5 Integer c=new Integer(a);//手动装箱--通用 } }
自动拆箱
int d=b;//把包装类转化为基本类--自动拆箱 int f=b.intValue();//手动拆箱
3.1异常
1. 什么是异常?
异常就是程序在运行时出现的意外情况,而导致程序无法正常往下执行[终止了]
2. 为什么需要异常处理?
异常处理的目的就是想让程序继续执行。
public class Test { public static void main(String[] args) { int a=10; int b=0; System.out.println("开始计算==============="); int result=a/b; System.out.println("结束计算=============="); } }
我们发现上面再14行发生异常,而导致14行以下的内容都无法正常执行。从而导致程序再14终止了。我们应该处理这种异常。能让程序继续执行。
3. 异常处理的方式?
java中提供了两种异常处理的方式:
第一种:
try{
可能发生异常的代码
}catch(异常类型 对象){
捕获异常
}finally{
异常的出口
}
第二种: 抛出异常throws
处理完异常后我们的程序可以继续执行了.
public class Test { public static void main(String[] args) { int a=10; int b=0; System.out.println("开始计算==============="); try { int result = a / b; }catch (ArithmeticException e){ System.out.println("捕获算术异常"); } System.out.println("结束计算=============="); } } try后面可以根多个catch捕获。不同的catch捕获不同的异常。 但是这样会先的比较麻烦。 public class Test { public static void main(String[] args) { Scanner scanner=new Scanner(System.in); System.out.print("请输入一个数字:"); String c1=scanner.next(); System.out.print("请输入二个数字:"); String c2=scanner.next(); System.out.printlna("开始计算==============="); try { int a=Integer.parseInt(c1); int b=Integer.parseInt(c2); int result = a / b; }catch (ArithmeticException e){ System.out.println("捕获算术异常"); }catch (NumberFormatException e){ System.out.println("格式化转化异常"); } System.out.println("结束计算=============="); } }
finally关键字:
使用异常处理中,作为最终执行的代码。不管有没有异常都会执行finally中代码。
后期使用在资源关闭中。是否执行了return,finally也会被执行
注意: try{}可以finally单独使用。try{}finally{}//没有捕获异常。
异常的根类(一个公共的父类)是Throwable.
Throwable下有两个子类:
Exception: 异常类,我们程序员可以处理的异常。一般使用该异常就了。
Error: 错误类。这种异常程序员无法处理。比如内存溢出。
根据多态,再异常捕获时可以使用Exception异常来捕获。
注意:如果你使用多个catch 范围大的必须放在访问下的后面。
eg:对于try{……}catch子句的排列方式:父类异常在前,子类异常在后。(子类异常包含父类异常)
把异常抛出,使用在方法名()后面. 抛给了方法调用者。 public static void main(String[] args) throws Exception {//JVM fun();//方法调用者 } public static void fun() throws Exception{ int a=10; int b=0; int c=a/b; }
如果我们抛出的异常为RuntimeException下的异常。不要强制调用者处理。
4. throw关键字
我们前面讲解的异常,都是程序自己产生的异常对象。 我们也可以自己定义异常对象。并把该异常对象抛出。
throw是在代码块内用来抛出具体异常的,而throws是在方法签名中用来声明可能抛出的异常类型的。
5. Exception异常类中常用的方法?
getMessage():获取异常信息
toString():获取异常信息以及异常种类
printStackTrace():打印异常信息以及异常种类和异常发生的位置
6. 自定义异常
当系统提供的异常类型无法满足客户需求时,程序员可以自己定义异常类型。目的可以达到见名知意
创建一个异常类并继承RuntimeException
public class AgeException extends RuntimeException {
//创建一个构造函数
public AgeException(String msg){
super(msg);
}
}
使用自定义的异常类
4.IO流
I/O是Input/Output的缩写,用于处理数据传输。如读/写文件、网络通讯等。
Java程序中,对于数据的输入和输出操作以”流(stream)”的方式进行。
java.io包下提供了各种”流“类和接口,用以获取不同种类单独数据,并提供方法输入或输出数据。
输入input:读取外部数据(磁盘、光盘等储存设备的数据)到程序(内存)中。
输出output:将程序(内存)数据输出到磁盘、光盘等存储设备中。
file只能对文件进行操作,但是无法对文件中的内容进行操作。IO流是针对文件的内容操作的一个类集合。
流的方向:输入流和输出流
4.0 IO流中的File文件对象
获取文件的相关信息
getName:文件名、getAbsolutePath绝对路径、getParent父文件、length长度、exists判断是否存在、isFile是否为文件、isDirectory是否为目录(目录也是一种特殊的文件)
获取一个列表对象list();
获取一个目录下的所有文件和子目录 listFiles()
在java jdk关于对文件【目录和文件】的操作都封装到File类。该类中包含了文件的各种属性以及操作方法。该类放在jdk–java.io包下
创建文件对象:File file=new File(“路径”);
创建新文件: createNewFile();
创建目录: 一级mkdir() 多级mkdirs();
删除文件和空目录: delete();
重命名: renameTo(File file)
public class Test02 { public static void main(String[] args) { File file01=new File("D:\\aaaaaaa"); // File file01=new File("zhenshuai.txt"); //获取文件名 String name = file01.getName(); System.out.println("文件名:"+name); //获取文件的父路径 String parent = file01.getParent(); System.out.println("父路径:"+parent); //获取文件相对路径 String path = file01.getPath(); System.out.println("文件路径:"+path); //绝对路径 String absolutePath = file01.getAbsolutePath(); System.out.println(absolutePath); System.out.println("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"); //获取该目录下所有的子文件名 String[] list = file01.list(); for(String s:list){ System.out.println(s); } System.out.println("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"); //获取当前目录下的所有子文件对象 File[] files = file01.listFiles(); for(File f:files){ String absolutePath1 = f.getAbsolutePath(); System.out.println(absolutePath1); } } }
exists:判断文件或目录是否存在
boolean exists = file01.exists();
System.out.println(“文件是否存在”+exists);
directory:判断文件是否为目录
boolean directory = file01.isDirectory();
System.out.println(“该文件是否为目录:”+directory);
案例:
package test12; import com.sun.corba.se.spi.orbutil.fsm.FSM; import java.io.File; / * @program: test * @description: 查询某个目录下所有的文件 * 思路:循环遍历查找不是目录的文件输出 * ①判断:是否为目录, * 是---一直遍历 * 遍历的条件是:把文件目录拿过来放到一个数组中查找 * 不是----说明是文档,直接输出文件名字 * @author: 王佳瑶 * @create: 2024-04-18 14:59 / public class file01 { public static void main(String[] args) { //实例化对象,把要查找的文件路径交给一个引用对象名 File file = new File("C:\\Users\\30391\\Desktop\\java基础二\\day03\\WJY"); listFile(file);//调用实现方法 } public static void listFile(File file){//创建一个函数,用于实现查找功能,带参的方法,参数类型为File //判断是否为目录 if (file.isDirectory()){//默认为true //是的情况---存放在数组中,方便循环遍历查找 File[] files = file.listFiles(); for (File f:files){ //查找第一层,不知道有多少层 //递归调用 //一直到条件不满足跳出 listFile(f); } }else { //要查找的情况,不是目录就是文件的情况,打印输出 System.out.println("文件名为"+file.getName()); } } }
4.2流的分类
字符流:只能操作文字,.txt文本
字节流:文字、图片,视频,音频等都可以
IO流体系图
文件vs流
FileInputStream()字节输入流
使用 FileInputStream 读取文件,并将文件内容显示到控制台。
字节输入流的父类InputStream。
package test12; import java.io.*; / * @program: test * @description: FileInputStream字节输入流 * 把w.txt文件中的内容读取到(程序内存中)控制台 * @author: 王佳瑶 * @create: 2024-04-18 16:16 / public class file02 { public static void main(String[] args) { //创建一个字节输入流(引用)对象 FileInputStream fins = null; try { fins = new FileInputStream(new File("w.txt")); int a = 0; while ((a = fins.read())!=-1){ char c = (char) a; System.out.print(c); } /* System.out.print((char) fins.read()); System.out.print((char) fins.read()); System.out.print((char) fins.read()); System.out.print( fins.read()); System.out.print(fins.read());*/ } catch (Exception e) { throw new RuntimeException(e); }finally { if (fins != null) { try { fins.close(); } catch (IOException e) { throw new RuntimeException(e); } } } } }
FileOutputStream()字节输出流
字节输出流的父类:OutputStream
1)使用 FileOutputStream 在 w.txt 文件,中写入 “hello,world”.
如果文件不存在,会创建文件(注意:前提是目录已经存在 )
2)编程完成图片/音乐 的拷贝
1. new FileOutputStream(filePath) 创建方式,当写入内容是,会覆盖原来的内容
2. new FileOutputStream(filePath, true) 创建方式,当写入内容是,是追加到文件后面
//写入字符串 String str = “hsp,world!”; //str.getBytes() 可以把 字符串-> 字节数组 //fileOutputStream.write(str.getBytes());
package test12; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; / * @program: test * @description: OutputStream输出流 * @author: 王佳瑶 * @create: 2024-04-18 16:43 / public class file03 { public static void main(String[] args) { OutputStream os = null; try { os = new FileOutputStream("w.txt",true);//默认不加true,是覆盖原来的内容 String w = "天气晴朗";//有true是追加后面 os.write(w.getBytes()); } catch (IOException e) { throw new RuntimeException(e); } finally { try { if (os != null) { os.close(); } } catch (IOException e) { throw new RuntimeException(e); } } } }
通过流完成文件的复制。(这种效率很慢)
先输入(要复制的对象地址)再输出(要复制到哪里的地址)。就是可完成复制。
package test12; import java.io.*; / * @program: test * @description: 文件(文档、音频、视频等)复制 //步骤: ①定义一个输入流和一个输出流对象 ②把要处理的文件给输入流 ③再定义新的路径给输出流 ④当输入流的内容不为空时,把输入流的内容写进输出流里 ⑤先关闭输入流,再关闭输出流(在这里先关谁都可以) * @author: 王佳瑶 * @create: 2024-04-18 16:59 / public class file04 { public static void main(String[] args) { InputStream is = null; OutputStream os = null; try { //输入流 is = new FileInputStream(new File("C:\\ruanjian\\.mp4")); //输出流 os = new FileOutputStream("C:\\ruanjian\\copy.mp4"); int a = 0; while ((a=is.read())!= -1){ os.write(a); } } catch (IOException e) { throw new RuntimeException(e); } finally { try { if (is != null) { is.close(); } if (os != null) { os.close(); } } catch (IOException e) { throw new RuntimeException(e); } } } }
FileReader()字符输入流
Reader它是字符输入流的一个父类,它也是抽象类,常见的子类FileReader.以字符为单位。
package test12; import java.io.File; import java.io.FileReader; import java.io.IOException; import java.io.Reader; / * @program: test * @description: read字符输入流 * @author: 王佳瑶 * @create: 2024-04-18 17:28 / public class file06 { public static void main(String[] args) { Reader r = null; try { r = new FileReader(new File("w.txt")); int a = 0; while ((a=r.read())!=-1){ char c = (char) a; System.out.print(c); } } catch (IOException e) { throw new RuntimeException(e); } finally { try { if (r != null) { r.close(); } } catch (IOException e) { throw new RuntimeException(e); } } } }
FileWrite()字符输出流
Write类,它是所有字符输出流的父类,输出的内容以字符为单位。它下面常用的子类FileWrite
package test12; import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.io.Writer; / * @program: test * @description: FileWrite * @author: 王佳瑶 * @create: 2024-04-18 17:20 / public class file05 { public static void main(String[] args) { Writer w = null; try { w = new FileWriter(new File("w.txt"),true); String str = "你好高元浩!"; w.write(str); } catch (IOException e) { throw new RuntimeException(e); } finally { try { if (w != null) { w.close(); } } catch (IOException e) { throw new RuntimeException(e); } } } }
缓冲流
常用的缓冲流: BufferedInputStream 和BufferOutputStream 缓冲流是作用在流上。
package test12; import java.io.*; import java.nio.file.Files; / * @program: test * @description: 用缓冲流copy视频 * @author: 王佳瑶 * @create: 2024-04-18 18:59 / public class test09 { public static void main(String[] args) { //开始时间 long l1 = System.currentTimeMillis(); InputStream is = null; BufferedInputStream bis = null; OutputStream os = null; BufferedOutputStream bos = null; try { is = Files.newInputStream(new File("C:\\ruanjian\\.mp4").toPath()); bis = new BufferedInputStream(is); os = Files.newOutputStream(new File("C:\\ruanjian\\copy1.mp4").toPath()); bos = new BufferedOutputStream(os); int a = -1; while ((a=bis.read())!=-1){ bos.write(a); } } catch (IOException e) { throw new RuntimeException(e); } finally { try { if (bos != null) { bos.close(); } if (bis != null) { bis.close(); } if (os != null) { os.close(); } if (is != null) { is.close(); } } catch (IOException e) { throw new RuntimeException(e); } } //结束时间 long l2 = System.currentTimeMillis(); System.out.println("耗时:"+(l2-l1)); } }
对象流
操作java类的对象,把java类对象写入到文件中,或者从文件中读取写入的java对象。
ObjectOutputStream序列化:把内存中的java对象写入到文件中的过程
ObjectInputStream反序列化:把文件中的对象读取到内存中
package test12; import java.io.*; import java.nio.file.Files; / * @program: test * @description: 对象流:序列化ObjectOutputStream对象输出(往文件中添加对象) * 反序列化ObjectInputStream在控制台输出文档的内容 * @author: 王佳瑶 * @create: 2024-04-18 19:24 / public class file10 { public static void main(String[] args) { //write(); read(); } //在控制台打印文档中的内容,读取,输入流 public static void read(){ InputStream is = null; ObjectInputStream ois = null; Object o = null; try { is = Files.newInputStream(new File("w.txt").toPath()); ois = new ObjectInputStream(is); o = ois.readObject(); } catch (Exception e) { throw new RuntimeException(e); } finally { try { if (ois != null) { ois.close(); } if (is != null) { is.close(); } System.out.println(o); } catch (IOException e) { throw new RuntimeException(e); } } } //往文档写东西,对于编程代码来说实现时输出流 public static void write(){ Student wjy = new Student("王佳瑶", 23); //对象输出 OutputStream os = null; ObjectOutputStream ops = null; try { os = new FileOutputStream(new File("w.txt")); ops = new ObjectOutputStream(os); ops.writeObject(wjy); } catch (IOException e) { throw new RuntimeException(e); } finally { try { if (ops != null) { ops.close(); } if (os != null) { os.close(); } } catch (IOException e) { throw new RuntimeException(e); } } } } class Student implements Serializable { 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 + '}'; } }
5.集合
集合: 它就是一个容器,允许存放若干个对象元素。
数组: 它也是一个容器,它里面允许放在相同类型的元素。
数组缺陷: 它只能放置同一类型,它的长度是固定。而集合里面可以放置任意类型的元素,而且长度不限【int最大长度】。
java中提供了很多集合接口和类。根据底层的结构不同。 它就是集合的体系结构。
5.1Collection
他是单值集合的根(接口),如果想要使用Collection集合中的功能,需要创建该接口的子类。以ArrayList为例,集合既然是容器,无外乎包含的功能就是增、删、改、查。
package test13; import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; / * @program: test * @description: 从集合里添加移除查询ArrayList * @author: 王佳瑶 * @create: 2024-04-19 09:11 / public class InterFace01 { public static void main(String[] args) { Collection c1 = new ArrayList(); Collection c2 = new ArrayList(); //添加 //单个 c1.add("你好"); c1.add("you,too."); c2.add("今天天气晴朗"); c2.add("是不错"); //多个 c1.addAll(c2); System.out.println(c1); //移除 c1.remove("你好"); c1.remove(c2); System.out.println(c1); //查询 int size = c1.size(); System.out.println("元素的个数为:"+size); //①循环增强的方式 for (Object o:c1){ System.out.println(c1); } //②迭代器的方式,hasNext():查找迭代器是否存在元素,next()指针下移并获取元素 Iterator iterator = c1.iterator(); while (iterator.hasNext()){//判断迭代器中是否为空 Object o = iterator.next();//指针下移并获取元素 System.out.println(o); } //清空集合 c.clear(); System.out.println(c); } }
5.2List:有序允许元素重复
Collection它是所有单值集合的根接口,它下面有两个子接口。List和Set.
List: 有序允许元素重复。
Set: 无序不可重复
package test13; import java.util.ArrayList; import java.util.List; / * @program: test * @description: List有序允许重复,Set无序不可重复 * @author: 王佳瑶 * @create: 2024-04-19 15:41 / public class List01 { public static void main(String[] args) { List list = new ArrayList<>(); //添加元素 list.add("01"); list.add("02"); list.add("03"); list.add(3,4);//指定位置添加 list.add(1,"02");//有序,直接添加,允许重复 //删除--根据下标删除 list.remove(1); //修改--指定位置修改 list.set(1,"高元浩"); System.out.println(list); //查找 //①--根据下标获取集合中的元素 Object o = list.get(1); System.out.println(o); //②--遍历集合,根据下标,//查找每一个 for (int i = 0; i < list.size(); i++) { Object ol = list.get(i); System.out.println(ol); } } }
5.3Set集合:无序不可重复
package test13; import java.util.HashSet; import java.util.Set; / * @program: test * @description: Set无序不可重复 * @author: 王佳瑶 * @create: 2024-04-19 15:55 / public class Set01 { public static void main(String[] args) { Set set = new HashSet<>(); Set set1 = new HashSet(); set.add("1"); set.add("2"); set1.add("1"); set1.add("2"); set1.add("3"); set.addAll(set1);//无序,不可重复 System.out.println("长度为:"+set.size()+"\n"+set); } }
5.4ArayList查询效率快:名.get(索引值)
List的子类,具备list的特点之外,
还具备自己的特点: 它的底层使用数组,查询效率快:名.get(索引值),
缺点: 中间:插入和删除慢–因为设计到元素的位移.
5.5(面试题)LinkedList增删速度快:add()/remove()
它也属于List的子类,它的底层使用链表结构。特点: 增删速度快,查询速度慢。
5.6ArrayList和LinkedList比较
5.7(面试题)HashSet无序,不允许重复
Set的子类,拥有和Set接口一样的方法。
底层使用hash表。按照hashcode以及equals方法比对判断元素是否重复的。
流程:先执行Hashcode方法,如果值不相同,则认为不同元素,不执行equals方法了,
如果值相同,则执行equals方法,
equals也相同,则认为相同元素。
5.8常用
5.9泛型
观察: 创建集合时<E> 他就是泛型标志, 限制集合中元素的类型。如果没有指定泛型,那么集合中可以存放任意类型的对象Object。
public class Test05 { public static void main(String[] args) { //集合中只能添加Student类型 LinkedList<Student> linkedList=new LinkedList(); //你在获取值的时候,它的类型就固定了 linkedList.add(new Student("张三",25)); linkedList.add(new Student("李四",25)); for(int i=0;i<linkedList.size();i++){ Student student = linkedList.get(i); } } }
5.10 TreeSet:自动排序
是set的子类,它的底层使用的是红黑二叉树,它里面的元素会自动按照ASCII码值的排序。
public class TreeSetTest01 { public static void main(String[] args) { TreeSet<String> treeSet = new TreeSet<>(); treeSet.add("3"); treeSet.add("2"); treeSet.add("1"); treeSet.add("4"); //自动按照ASCII码表排序 System.out.println(treeSet); //遍历输出。 // ①增强循环(JDK1.5之后使用) for(String t:treeSet){ System.out.println(t); } // ②迭代器(JDK1.5之前使用) Iterator<String> iterator = treeSet.iterator(); while (iterator.hasNext()){ System.out.println(iterator.next()); } } }
往TreeSet中添加一个对象,字符串实现Comparable接口,该接口是一个排序规则接口。我们需要为该类实现Comparable接口。
排序规则:返回一个int类型。
正整数:表示当前添加的元素比容器中要比较的元素大
负数:表示当前的元素比容器中的元素小。
0:表示相同的元素。
我们在创建Food类对象时,实现类排序规则的接口,如果你往TreeSet中添加的对象,是别人写好的类,没有实现排序规则的接口。如果别人写的类排序规则满足不了你的要求。比如按照字符串的长度排序。这时候就需要用到定制排序这种来写,以此来解决每个类都有独特的功能需求。
public class Food implements Comparable<Food>{//自动排序 private String name; private int price; @Override public int compareTo(Food o) { int p = this.price - o.price; if (p == 0){ this.name.compareTo(o.name); } return p; } public Food() { } public Food(String name, int price) { this.name = name; this.price = price; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getPrice() { return price; } public void setPrice(int price) { this.price = price; } @Override public String toString() { return "Food{" + "name='" + name + '\'' + ", price=" + price + '}'; } } public class TestFood { public static void main(String[] args) { TreeSet<Food> t = new TreeSet<>(new Comparator<Food>() {//定制排序 @Override public int compare(Food o1, Food o2) { int i = o1.getPrice()-o2.getPrice(); if (i == 0){ o1.getName().compareTo(o2.getName()); } return i; } }); t.add(new Food("小鸡炖蘑菇",65)); t.add(new Food("大盘鸡",68)); t.add(new Food("小鸡炖小鸡",60)); System.out.println(t); } }
5.11 Map以及Map下的子类
上面的集合都是单值集合,而Map它是一个键值对集合。Map集合中的元素有key和value组成。底层实现类HashMap
Map中方法:—子类HashMap
- 存放元素: put(key,value)
- 获取Map元素个数: size()—返回类型int
- 根据key获取对应的value: get(key)
- 判断某个key是否在map中: containsKey()—–true/false
- 清空: clear()
- 根据key移除: remove()
- 获取map中所有key: keySet()
- 遍历Map对象
public class MapTest { public static void main(String[] args) { Map<String, Object> m = new HashMap<>(); //存放元素:map(key,value) m.put("高元浩",24); m.put("王佳瑶",23); m.put("wjy",19); //获取map元素的个数:size() int size = m.size(); System.out.println("元素的个数:"+size); //根据key获取对应的value:get(key) System.out.println(m.get("wjy"));; //判断某个key是否在map中:containsKey()--true/false System.out.println(m.containsKey("wjy")); //根据key移除:remove() m.remove("wjy"); //获取Map中所有的key元素 System.out.println(m.keySet()); //遍历Map对象 for (String k : m.keySet()){ System.out.println(k+"--->"+m.get(k)); } //判断指定key是否在Map中存在 boolean b = m.containsKey("wjy"); System.out.println(b); //清空:clear() m.clear(); System.out.println(m); } }5.12(面试题)HashMap底层原理
JDK1.7底层使用的是数组+链表
JDK1.8以后底层使用数组+链表+红黑二叉树
根据key计算除Hash值,根据Hash值找到对应的数组位置,查看该位置是否存在元素。
如果该位置没有元素,则存在k—v;
如果有元素,比较equals,如果equals不同,hash冲突
如果hash冲突的个数比较多,使用红黑二叉树。链表转化数冲突的个数超过8个,数组长度超过64位。
5.13Collections工具类(针对集合类)
Collections类是Java中针对集合类的一个工具类,其中提供一系列静态方法。
工具类中所有的方法都是静态方法: 直接通过类名调用。
动态添加元素-addAll();
复制并覆盖相应索引的元素–copy();
用T元素替换掉集合中的所有的元素。fill(list1,T);
洗牌—打乱元素中的元素–shuffle(list2);
对集合排序—-从小到大sort(list2);
—从大到小排序
Collections.sort(list2, new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return o1 – o2;
}
});
二分查找—要求集合是有序的。如果找到返回该元素所在的下标.如果没有找到返回负数binarySearch(list2,3);
max、min、replace、replaceAll、reverse、。。。
sort()排序 binarySearch()二分查找 shuffle()洗牌。 fill填充 copy();
package Test14; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.List; / * @program: test * @description: * @author: 王佳瑶 * @create: 2024-04-20 15:26 / public class Collections_ { public static void main(String[] args) { //创建第一个有序集合,类型为整形 List<Integer> list1=new ArrayList<>(); list1.add(1); list1.add(2); //创建第二个有序集合,类型为整形 List<Integer> list2 = new ArrayList<>(); //动态添加元素--list2里添加元素 Collections.addAll(list2,2,55,9,46,3,1,46); //复制并覆盖相应索引的元素。 // 复制覆盖,在第一个数组内添加第二个数组的数据并从下标为0的开始 // ---在list2中添加list1内的数据 Collections.copy(list2,list1); //用9元素替换掉集合中的所有的元素。 Collections.fill(list1,9); //洗牌---打乱元素中的元素。 Collections.shuffle(list2); //对集合排序----从小到大 Collections.sort(list2); //---从大到小排序 Collections.sort(list2, new Comparator<Integer>() { @Override public int compare(Integer o1, Integer o2) { return o1 - o2; } }); //二分查找---要求集合是有序的。 // 如果找到返回该元素所在的下标.如果没有找到返回负数 int i = Collections.binarySearch(list2,3); System.out.println(i); System.out.println("list1:"+list1); System.out.println("list2:"+list2); } }
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/111001.html




































































































