Java稈序开发基础
在控制台输出:
System.out.println();会把括号的内容转换为字符串输出在控制台,并且换行
System.out.printf(); 语句在输出时同时给出格式字符串和参数列表,参数按对应格式要求输出
System.out.print();会把括号的内容转换为字符串输出(不换行)
格式化打印,格式化字符串
%d:整数 %f:浮点数
%s:字符串 %0md:m整数占m位,位数不足用0补齐 %m.nd: n小数的位数
//System.out.println();
System.out.println("我位于第一行,输出完成后会换行....");
System.out.println("我位于第二行.....");
//System.out.printf("");
System.out.println("个人详细信息为:");
System.out.printf("姓名=%s,%n年龄=%d,%n体重=%5.2f公斤","Jessica",18,50f);
//System.out.print("");
System.out.print("我位于第一行,输出完成后不会换行....");
System.out.print("我在它后面");
在控制台输入
Scanner 变量名= new Scanner(System.in); //System.in 代表标准输入也就是键盘输入
利用Scanner对象获的输入项的方法为nextXxx(),Xxx可以是Int,Long等基本数据类型。字符串是next()。
Scanner input= new Scanner(System.in);
String in=input.next();
int in2=input.nextInt();
变量和表达式
标识符和关键字
标识符
程序中各个元素命名时使用的符号称为标识符。比如Java中的工稈名,包名,类名,方法名,变量名,参数名都是标识符
-
Java标识符定义时,遵循的规则
- 标示符可由 字母, 数字, 下划线(_), 美元($)符号组成,其中数字不能作为首字符。
- 标识符不能是Java的关键字和保留字,但可以包含关键字和保留字。
- Java语言区分大小写
关键字:Java语言中有一些有特殊用途的单词,称之为关键字(keyword)。在程序中,关键字不能作为标识符使用,否则会引起错误。Java中所有关键字的字母都是小写。
保留字:保留字是指Java从现在还没有用到在随着Java版本的升级可能会用到的关键字,Java中的保留字不要有两个:goto和const。在程序保留字不能作为标识符使用。
注释
单行注释://
多行注释:以/*
表示注释开始,而*/
表示注释结束
/*
*这是一个多行注释
* Java真好用
* */
文档注释:在Java语言中,使用/**
和*/
将程序中需要注释的内容包含起来,/**
表示文档的开始,而*/
表示注释结束
变量和常量
编程的本质就是对内存中的数据进行访问和修改,程序所用的数据都会保存在内存中。程序员需要一种机制来访问或修改内存中的数据,这种机制就是变态。
1.变量:声名变量,只要指定变量的类型和变量名即可。
变量必须先声明,后使用
数据类型 变量名 [ = 初始值];
//声明变量方法一
String name1="Tom";
//声明变量方法二(分开写)
String name2;
name2="Li";
2.常量:所谓常量,就是在程序运行过程中不能改变的了。其该内存中的数只能读取而不能修改。在Java语言中,使用final关键字声明常量。
final 数据类型 常量名 [ = 数值];
声明一个常量PI表示圆周率的值为3.1415
final double PI = 3.1415;
数据类型:
基本数据类型的数据占用内存的大小是固定的,但内存中传入的是数据本身。
引用数据类型在内存中存入的是数据的存放地址不并不是数据本身。
- 数据类型
- 基本数据类型
- 数值型
- 整型
- 浮点型
- 字符型
- 布尔型
- 数值型
- 引用数据类型
- 类
- 接囗
- 数组
- 基本数据类型
基本数据类型
(1)整型[字节型(byte),短整型(short),整型(int),长整型(long)]
注:
byte内存分配 1 个字节,占 8 位(8bit)表示的范围是:-128(-2的7次幂)~127(2的7次幂-1)
short内存分配 2 个字节,占 16 位表示的范围是:-32768(-2的15次幂-1)~32767(2的15次幂)
int内存分配 4 个字节,占 32 位表示的范围是:-2147483648(-2的31次幂)~2147483648(2的31次幂-1)
short内存分配 8 个字节,占 64 位表示的范围是:-2的63次幂~2的63次幂-1
(2)浮点型
单精度浮点数(float型),float分配 4 个字节,占 32 位
float num=154.01f;//赋值为小数,必须加“F”(或“f”)
float num_1=154865475564f;//赋值超出int取值范围,必须加“F”(或“f”)
float num_2=154;//赋值未超出int取值范围,可以加“F”(或“f”)
float num_3=154;//赋值未超出int取值范围,可以不加“F”(或“f”)
双精度浮点数(double型),float分配 8 个字节,占 64 位
java语言浮点类型默那浮点类型默认的是double类型,当然也可以通过福蝶愫后添加d和D后缀显示是double类型,但通常没必要。
double a=1234567.89; //声明double型并赋值
-
Java语言浮点数的两种表现形式
- 十进制:就是普通的浮点数。
-
科学计数法:5.12E2(即5.12*10的2次方)
注:只有浮点数才能使用科学计数方
(3)字符型
char:占 2 个字节内存,字符型的取值必须用(’’)括起来
char sex='男'; //将汉字男赋值给char类型
-
字符串的三种表现形式:
-
直接通过单个字符串来指定字符串的取值,如:‘A’,‘9’,'我’等
-
通过转义字符串表示的取值,如:’\n’,’\r’等
-
直接用Unicode值来表示
java的转义字符串
转义字符串 | 含义 | Unicode |
---|---|---|
\’ | 单引号 | \u0027 |
\" | 双引号 | \u0022 |
\\ | 反斜扛 | \u005c |
\r | 回车 | \u000d |
\n | 换行 | \u000a |
\t | 制表符 | \u0009 |
\b | 退格 | \u0008 |
(4)布尔型
布尔型只有一种,用于表达逻辑上的“真”或“假”。在Java语言中,不尔类型只有true或false
布尔类型用关键字boolean
进行声明
boolean b1=true; //声明boolean型变量b1,并赋值为true
boolean b2=false; //声明boolean型变量b2,并赋值为false
引用数据类型
Java援助除八种基本数据类型之外的数据类型被称为引用数据类型,也称复合数据类型。包括引用,接口引用,以及数组引用。在程序中声明的引用类型变量值只是为该对象起一个名字,或者说是该对象的引用,变量值是对象在内存空间的储存地址而不是对象本身,因此称为应用类型。
字符串String就是引用数据类型。string是一Java类,因此是一种类引用
String name="Tom"; //此时name表示的内存中存放的并不是值“Tom”,而是“Tom”的存储存的地址
Scanner input = new Scanner(System.in);
就是一种引用数据类型
数据类型转换
(1)自动类型转换(表示范围小的可以向表示范围大的转换)
Java支持数据类型的顺序
byte---->short----->int----->long----->float----->double
char-------------------^
int num='a';
System.out.println(num);
double num1=num;
System.out.println(num1);
(2)强制类型转换
表达式(有可能会造数据丢失,这种转换也叫“缩小转换”)
(数据类型)表达式
double num=12.5;
int num_1=(int)num;
System.out.println(num_1);
(3)字符转换为基本数据类型
在通常情况下,字符串不能直接转换为基本的数据类型,但通过基本类型对应的包装类则可以实现把字符串转化换基本类型。
基本数据类型 | 包装类 |
---|---|
boolean | Boolean |
byte | Byte |
short | Short |
int | Integer |
long | Long |
float | Float |
double | Double |
char | Character |
除了Character包装类外,其余的都提供一个parseXxx(String str)静态方法用于将字符串转换为基本数据类型
String str = "45";
int iValue=Integer.parseInt(str);
System.out.println(iValue);
运算符与表达式
表达式
表达式是由操作数与运算符组成。
操作数可以是变量,常量,也可以是方法;运算符类似于数学串的运算符号,如(“+”,“-”,“*”,“/”)等
运算符
(1)赋值运算符
赋值运算符运用于指定变量的变量值,使用“=”作为赋值运算符
int num_1=5; //将数据直接符给变量,为变量i符值为5
int num_2=num_1; //将一个变量赋给另一个变量
int num=num_1*num_2;//将表达式符给变量
(2)算术运算符
Java支持所有的算术运算符
符号 | 名称 | 含义 |
---|---|---|
+ | 加法运算符 | 将加法运算符“+”前后的两个操作数相加 |
- | 减法运算符 | 将减法运算符“-”前面的操作数减去后面的操作数 |
* | 乘法运算符 | 将乘法运算符“*”前后的两个操作数相乘 |
/ | 除法运算符 | 将除法运算符“-”前面的操作数除以后面的操作数 |
% | 余数运算符 | 将余数运算符“-”前面的操作数除以后面的操作数,的到一个整除的结果后剩下的值就是余数 |
++ | 自增运算符 | 自增运算符有两个要点:1是自增是单目运算符,只能操作一个数。2.只能操作作单伞数值型的变量,不能操作常量或表达式 |
– | 自减运算符 | 与自增基本相同只是将操作数减1 |
除法:
1.如果除法运算符的两个操作数都是整数,则结果也为整数
2.如果除法运算符的两个操作数都是浮点数,或有一个数为浮点数,则结果也为浮点数
//定义num_1,num_2
int num_1=5;
int num_2=12;
int num_3=num_1+num_2; // +法运算符
int num_4=num_1-num_2; // -法运算符
int num_5=num_1*num_2; // *法运算符
int num_6=num_2/num_1; // /法运算符
double num_12=num_2*1.0/num_1;// /法运算符
int num_7=num_2%num_1; // %法运算符
//自增
int num_8=num_1++; //先执行算术运算符然后再自增
System.out.println(num_1);
System.out.println(num_8);
int num_9=++num_1; //先自增然后再执行算术运算符
System.out.println(num_9);
//自减
int num_10=num_1--; //先执行算术运算符然后再自减
System.out.println(num_1);
System.out.println(num_10);
int num_11=--num_1; //先自减然后再执行算术运算符
System.out.println(num_11);
(3)关系运算符(比较运算符)
用于比较两个数的大小,结果是true或false
Java支持的有<(小于),>(大于),<=(小于等于),>=(大于等于),==(等于),!=(不等于)
(4)逻辑运算符
用于操作两个布尔类型的变量或常量
符号 | 名 | 解释 |
---|---|---|
&& | 逻辑与运算符 | 前后两个操作数都是true才返回true,否则返回false |
|| | 逻辑或运算符 | 前后两个操作数都是true,或有一为true才返回true,否则返回false |
! | 逻辑非运算符 | 如果操作数为true则返回false |
(5)位运算符
任何信息在计算符都以二进制的形式存在
符号 | 名 | 含义 |
---|---|---|
& | 按位与 | 当两位同时为1时才返回1 |
| | 按位或 | 只要有一位为即可返回1 |
~ | 按位非 | 单目运算符,将操作数的每一位(包括符号位)全部取反 |
^ | 按位异或 | 两位相同时返回0,不同返回1 |
>> | 右移运算符 | 11>>2 :11的二进制右移两位 |
<< | 左移运算符 | 11<<2 :11的二进制左移两位 |
>>> | 无符号右移运算符 |
(6)括号运算符
用来处理表达式的优先级
(7)三目运算符
运行规则:先对第一个操作逻辑表达式求值,true则返回表达式1,false返回表达式2
逻辑表达式? 表达式1:表达式2
String num1="0";
String num2="5";
String str=5>7?num1:num2;//String返回值的类型
运算符的优先级
优先级 | 运算符 | 运算符说明 | 结合性 |
---|---|---|---|
1 | . () [] {} , ; | 分隔符 | 由右至左 |
2 | ! ~ + - ++ – | 单目运算符 | 由右至左 |
3 | (type) | 强制类型转换运算符 | 由左至右 |
4 | * / % | 算术运算符 | 由左至右 |
5 | + - | 算术运算符 | 由左至右 |
6 | << >> >>> | 移位运算符 | 由左至右 |
7 | > >= < <= | 关系运算符 | 由左至右 |
8 | == != | 关系运算符 | 由左至右 |
9 | & | 位逻辑运算符 | 由左至右 |
10 | ^ | 位逻辑运算符 | 由左至右 |
11 | | | 位逻辑运算符 | 由左至右 |
12 | && | 逻辑运算符 | 由左至右 |
13 | || | 逻辑运算符 | 由左至右 |
14 | ?: | 三目运算符 | 由右至左 |
15 | = += -= *= /= &= |= ~= %= <<= >>= >>>= | 赋值运算符 | 由右至左 |
if条件语句,switch分支语句
if条语句
if语句使用布尔表达式或布尔值作为分支条件来进行分支控制
第一种形式
if(判断条件){
执行语句;
}
Scanner input = new Scanner(System.in);
System.out.print("输入数字:");
int num=input.nextInt();
if (num==1){
System.out.println("if执行成功");
}
System.out.println("执行成功");
第二种形式
if(判断条件){
判断条件true时执行;
}else{
判断条件false时执行;
}
Scanner input = new Scanner(System.in);
System.out.print("输入数字:");
int num=input.nextInt();
if (num==1){
System.out.println("件条为true");
}else {
System.out.println("条件为false");
}
System.out.println("执行成功");
第三种形式
if(判断条件1){
判断条件1,true时执行;
}else if (判断条件2){
判断条件2,true时执行;
}
.....//可以有多个(else if),语句
else{//可以省略
判断条件false时执行;
}
Scanner input = new Scanner(System.in);
System.out.print("输入数字:");
int num=input.nextInt();
if (num==1){
System.out.println("件条1为true");
}else if (num==2){
System.out.println("件条2为true");
}else if (num==3){
System.out.println("件条3为true");
}else {
System.out.println("条件为false");
}
System.out.println("执行成功");
switch语句
语法格式
控制表迖式的数据类型只能是(byte,short,int,char,枚举,String)这几种,不能是布尔类型
switch (表达式){
case 选择值1:
语句块主体1
break;
case 选择值2:
语句块主体2
break;
..........
case 选择值n:
语句块主体n
break;
default:
语句块主体n+1
}
流程:switch先计算表达式,然后再匹配case,然后执行对应的语句主体,直到遇到break才停止,如果没有匹配的case,则执行default语句。
Scanner input = new Scanner(System.in);
System.out.print("请输入你要执行的语句:");
int choice=input.nextInt();
switch(choice){
case 1:
System.out.println("执行了语句1");
break;
case 2:
System.out.println("执行了语句2");
case 3:
System.out.println("执行了语句3");
break;
case 4:
System.out.println("执行了语句4");
break;
default:
System.out.println("没有执行case");
}
重复迭代-循环结构
while循环
[初始化语句]
while(循环判断的条件){
循环体语句块
[迭代语句]
}
int i=0;
System.out.println("这是while");
while (i<10){
System.out.println("i的值为"+i);
i++;
}
过程:
do…while
do…while与while的区别在do…while先执行一遍在判断,while先判断在执行
[初始化语句]
do{
循环体语句块
[迭代语句]
}while(循环判断条件);
int i=0;
System.out.println("这是while");
while (i<0){
System.out.println("i的值为"+i);
i++;
}
System.out.println("这是do....while");
do {
System.out.println("i的值为"+i);
}while(i<0);
for循环
for([初始化语句];[循环判断条件];[迭代语句]){
循环语句块
}
for(int i=0;i<=5;i++){
System.out.println("i的值为"+i);
}
break语句
完全结束一个循环,跳出循环体。
continue语句
continue语句的作用是跳过本次循环体中余下尚未执行的语句,立即进行下一次的循环条件判定,可以理解为仅结束本次循环。
Java面向对象编程
方法
定义方法:方法就是为了完成一个操作而组合在一起的语句组,方法的定义由方法的名称、参数、返回值类型以及方法体组成
形式参数:定义在方法头中的变量成为形式参数
实际参数:当调用方法时,就给参数传递一个值,这个值成为实际参数
方法签名:方法名和参数列表构成了方法签名
-
调用方法:
- 存在 static修饰符:通过类名.方法名调用
- 通过new关键字调用构造方法,这种是在实例化对象时使用的方式
- 通过对象名.方法名进行调用,这是最普通的也是最常见的一种调用方式
- 注形式参数与实际参数一致,类型相同或可以自动类型转换
链接: https://blog.csdn.net/qq_40136594/article/details/83996659.
-
形式参数
- 定义在方法头中的变量成为形式参数 实际参数
- 当调用一个方法时,就给参数传递一个值,这个值就成为一个实际参数 方法签名:
- 方法名和参数列表构成方法签名 返回值:
-
如果方法中没有返回值,返回值类型为
void
-
如果方法有方法中有返回值,方法中必须使用
return
返回该值,返回类型为该返回值的类型
注:方法至多有一个返回值,不能有多个返回
1.计算用户数入数的相加和
import java.util.Scanner;
/*
*
* */
public class Demo {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
System.out.print("请输入数字:");
int num_1=in.nextInt(); //接受用户输入的数
System.out.println(num_1+"位置上的数相加和"+numSum(num_1)); //打印,调用方法
}
//定义方法且返回值为int
public static int numSum(int num_1){
int sum=0; //接受和
while (num_1!=0){
sum+=num_1%10; //%取余,取得个位上的数
num_1/=10;
}
return sum;
}
}
2.打印用户数入的一年有多少天
import java.util.Scanner;
public class Demo {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
System.out.print("请输入年份:");
int year=in.nextInt();
System.out.println(year+"年一共有"+yearDay(year));
}
public static int yearDay(int year){
if (year%4==0&&year%100!=0||year%400==0)
return 366;
else
return 365;
}
}
面向对象的基本概念
-
类是具有相同属性和共同行为的一组对象的集合
- 属性:对象所拥的各种特征(静态的)
- 方法:对象执行的行为(动态的)
- 类是一个高度抽象的概念
- 类定义了对象将会拥有的属性和方法 类和对象的关系:类是对象的抽象,对象是类的实例化
- 从对象中抽取属性和方法的共同特征,从而抽取出类
- 类是对象的类型,在定义了一个类以后,就等于是定义了一个新的数据类型 类的使用
- 类是java程序的基本单元
- 类的基本结构(是啥?类名。啥特征?属性。能做啥?方法)
- 类是对象产生的模板
对象的产生和使用
类名 对象名 = new 类名 ([参数1,参数2.....])
类
class 类名 {
//定义属性部分
属性1的类型 属性1;
属性2的类型 属性2;
…
属性n的类型 属性n;
//定义方法部分
方法1;
方法2;
…
方法m;
}
public class Circle {
//属性
double radius;
String filColor;
//方法
public double getArea(){
//获得面积
return Math.PI*radius*radius;
}
public double getDiameter(){
//获得周长
return Math.PI*2*radius;
}
//测式
public static void main(String[] args) {
Circle c1=new Circle(); //创建c1对象
c1.radius=5; //给属性赋值,(对象名.属性)
System.out.println(c1.getArea()); //输出,调用方法(对象名.方法())
System.out.println(c1.getDiameter()); //输出,调用方法
}
}
封装
-
封装的概念:
-
将属性及方法相结合,共同体现对象的特性,称之为封装(Encapsulation)
-
对象的属性和方法通常被封装在一起,共同体现事物的特性, 二者相辅相承,不能分割
什么是封装:封装,就是隐藏实现细节
-
将属性私有化,提供公有方法访问私有属性
-
通过这些公有方法访问私有属性
封装的实现:
-
1、修改属性的可见性来限制对属性的访问(把属性私有化)
-
2、为每个属性创建一对赋值(setter)方法和取值(getter) 方法,用于对这些属性的访问
-
3、在setter和getter方法中,加入对属性的存取限制
访问控制符:
-
private(当前类访问权限):如果类里的一个成员(包括成员变量、方法和构造器等)使用private访问控制符来修饰,则这个成员只能在当前类的内部被访问。很显然,这个访问控制符用于修饰成员变量最合适,使用它来修饰成员变量就可以把成员变量隐藏在该类的内部。
-
default(包(package)访问权限):如果类里的一个成员(包括成员变量、方法和构造器等)或者一个外部类不使用任何访问控制修饰,就称它为包访问权限的,default访问控制的成员或外部类可以被相同包下的其他类访问。
-
protected(子类访问权限):如果一个成员(包括成员变量、方法和构造器等)使用protected访问控制符修饰,那么这个成员既可以被同一个包中的其他类访问,也可以被不同包中的子类访问。在通常情况下,如果使用protected来修饰一个方法,通常是希望其子类来重写这个方法。
-
public(公共访问权限):这是一个最宽松的访问控制级别,如果一个成员(包括成员变量、方法和构造器等)或者一个外部类使用public访问控制符修饰,那么这个成员或外部类就可以被所有类访问,不管访问类和被访问类是否处于同一个包中,是否具有父子继承关系。
private | friendly | protected | public | |
---|---|---|---|---|
类本身 | ✔ | ✔ | ✔ | ✔ |
包内,子类 | ✔ | ✔ | ✔ | |
包内,非子类中 | ✔ | ✔ | ✔ | |
包外,子类 | ✔ | ✔ | ||
包外,非孒类 | ✔ |
访问控制符转自: https://www.cnblogs.com/suinlove/p/5147561.html
this super 调用方法 https://blog.csdn.net/lncsdn_123/article/details/79025525
构造方法
为什么需要构造方法:要简化对象初始化的代码,可以通过构造方法来解决
-
什么是构造方法
- 构造方法负责对象成员的初始化工作,为实例变量赋予合适的初始值
- 构造方法必须满足以下语法规则:(1、方法名与类名相同,2、没有返回类型)
- 如果没有创建构U盘横说竖说宅男宅女方系统会自动创建一个默认的构造方法(无参的),如果创䢖带参的构造方法,默认的方法就没了,必须显示的创建构造方法 构造方法
- 含义:类中的一个特殊的方法,它在 对象被创建的时候调用,用来把对象进行初始化赋值
- 特点:(方法名跟类名一致(大小写也要相同),没有返回值(连 void 都不写) )
使用构造方法:通过new关键字调用构造方法
方法的重载
-
重载方法必须满足以下条件:
- 方法名相同
- 方法的参数类型、个数、顺序至少有一项不相同(方法签名)
- 方法的返回类型可以不相同
- 方法的修饰符可以不相同
- 构造方法的重载是为让对象的初始化更加方便
调用重载方法时,Java 使用参数的类型和数量决定实际调用重载方法的哪个版本
/*
*完善钢材类
*封站装钢材类
*添加构造方法:不包含任何参数
* 包含长,宽,高三个参数
* 包含长,宽,高,价格四个参数
*类:class
* 标识符:字母,数字,_(下划线),$且数字不能数字当下划线
* Pascal:每个单词的首字母大写
*
* 属性
* 方法
*封装:
* 把属性封装,不能直接访问属性,只能通方法访问
* 歨骤:把属性私有化-private(只能在类的内部访问)
* 添加getter和setter方法
* */
import com.sun.xml.internal.ws.api.model.wsdl.WSDLOutput;
public class Steel {
//封装
private double height;
private double width;
private double length;
private double price;
//构造方法+重载
public Steel() {
}//无参
public Steel(double height, double width, double length) {
this.height = height;
this.width = width;
this.length = length;
}//三参
public Steel(double height, double width, double length, double price) {
this.height = height;
this.width = width;
this.length = length;
this.price = price;
}//四参
public double getHeight() {
return height;
}
public void setHeight(double height) {
this.height = height;
}
public double getWidth() {
return width;
}
public void setWidth(double width) {
this.width = width;
}
public double getLength() {
return length;
}
public void setLength(double length) {
this.length = length;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
public void printInfo(){
System.out.println("长度:"+this.length);
System.out.println("宽度:"+this.width);
System.out.println("高度:"+this.height);
System.out.println("价格:"+this.price);
}
//测式
public static void main(String[] args) {
Steel st1 = new Steel(410.0,20.0,50.0,60.0);
st1.printInfo();
}
}
继承和多态
继承
概念:面向对象程序设计中,在已有类上定意新类,不需要把类的内容重新书写一遍,这就叫继承
已有类叫基类或父类,在基础上建的叫派生类或子类
实现:关键字entends
[修饰符] class 子类 [extends 父类]
注:(1)子类只可有一个父类,父类可以有多个子类
(2)如果是孒类继承了父类,则子类自动具有父类的全部非私有的数据成员和成员方法
(3)字类可以定意自己的数据成员和成员函数,同时也可以修改父类的数据成员或重写父类的方法
(4)在Java中,Object类为特殊超类和基类,所有类都可以直接或间接的继承Object
多态
概念:多态是指Java运行时多态性。它是面向对象程序设计中从新的最强大机制,Java实现多态的基础是动态法调度,就是父类的某个方法被重写了,从各自产生自己的功能行为。
多彩的用法一般可以归结为两种,一种用法是使用父类声明的数组存储子类的对象。另一种是使用父类的声明作为方法的形参,子类对象作为实参传入
//父类Employee
public class Employee {
public String name;
public Employee(String name){
this.name=name;
}
public void showInfo(){}
}
//子类CommEmp,继承Employee
public class CommEmp extends Employee {
public String workStation;
public CommEmp(String name,String workStation){
super(name);
this.workStation=workStation;
}
public void showInfo(){//重写父类的方法
System.out.println("我是"+this.name+";工作岗位"+this.workStation);
}
}
//子类Manager,继承Employee
public class Manager extends Employee {
public String dep;
public Manager (String name,String dep){
super(name);
this.dep=dep;
}
public void showInfo(){//重写父类的方法
System.out.println("我是"+this.name+";我管理的部门是"+this.dep);
}
}
//类HR的judge方法使用父类Employee(数组)作为形式参数
public class HR {
public void judge(Employee[] emp){
for(int i=0;i<emp.length;i++){
emp[i].showInfo();
}
}
}
//类HR的judge方法使用父类Employee(数组)作为形式参数
public class HR {
public void judge(Employee[] emp){
for(int i=0;i<emp.length;i++){
emp[i].showInfo();
//形式上调用父类方法,实际会根据传入对象来调用
}
}
}
//测试类
public class Main {
public static void main(String[] args) {
Employee[] emp=new Employee[2];
//修攺数组的值
emp[0]=new CommEmp("普通员工张三","法外狂徒");
emp[1]=new Manager("管理者李四","财务部");
//创建HR的对象,调用里的方法
HR hr=new HR();
hr.judge(emp);
}
}
最终类
Java中的final关键字可以用来修饰类,方法和局部变量。final修饰的类叫最终类,此类不能被继承。final修饰的方法叫做最终方法,此法方法不能被重写。final修饰的变量实际上枏当于常量。此变量只能赋值一次。
抽象类
那不能生成实例化对象的类叫抽象类。
-
抽象类
- 抽象类和方法都必须用abstract来修饰
- 抽象类不能被实例化,也不能用new关键字去产生对象
-
抽象类只用声明,而不需要实现
注:含有抽象方法的类必须被声为抽象类,抽象类的子类必须重写所有的抽象方法后才能被实例化,否则这个子类还是抽象类
接囗和多态
接囗
https://www.runoob.com/w3cnote/java-interface-and-polymorphism.html
异常处理https://www.runoob.com/java/java-exceptions.html
使用数组进行数据存储
数组
数组的定义:数组是一个变量,存储相同数据类型的一组数据
-
使用数组四步走
- 1、声明数组(int[ ] a;)
-
数据类型 数组名[ ] ;(不是首选方法)
-
数据类型[ ] 数组名 ;(首选方法)
- 2、分配空间(a = new int[5]; )
-
数据类型[ ] 数组名 = new 数据类型[大小];
-
3、赋值,访问数组元素
数组名[index] = 8;
,index就是下标 - 4、处理数据(a [0] = a[0] * 10; )
数组一但创建它的长度是一定的,数组元素的下标的取值范围从0-数组.length-1
数组遍历
for语句遍历数组
for (int i=0;i<数组.lenght;i++){
//处理数组元素 数组[i]
}
int[] demo=new int[10];
for (int i=0;i<demo.length;i++){
demo[i]=3;
System.out.println("demo["+i+"]的值为"+demo[i]);
}
foreach语句的使用+toString
Arrays.toString()返回一个字符串
for(数据类型 单个元素的操作名:数组名){
//对数组的操作
}
注:数据类型必须与数组的数据类型一致
public static void main(String[] args) {
int[] items={10,0,0,10}; //定义数组
int i=0;
for(int item:items){//循环
i++;
if(item==0){ //判断是否为0
continue; //跳出当前循环
}
System.out.printf("执行了第%d次",i); //打印执行了几次
System.out.println(); //换行
}
System.out.println(Arrays.toString(items)); //toString打印数组
}
定义一个方法,调用方法对数组进行初始化
public static void main(String[] args) {
int i=0;
int[] response=new int[10]; //定义一个数组
System.out.println(Arrays.toString(ForDemo(response)));
//Arrays.toString打印字符串
}
//写一个方法,对数组进行初始化(虽然在生活中没用,但可以回顾一下知识点)
public static int[] ForDemo(int[] response){
for(int num=0;num<response.length;num++){
response[num]=num;
}
return response;
}
(1)Arrays.toString():返回一个字符串,该字符串代表数组串的所有元素
(2)Arrays.sort():对整个数组进行排序
(3)Arrays.binarySearch():使用二分搜索法来指定的数据值型和字符型数组,以获得指定的值所在位置
(4)Arrays.copyOf():复制指定数组到一个新的数组
(5)Arrays.equals():比较是否枏同,若长度相同,且值相同,返回true否则返回false
int i=0;
int[] response={5,10,2,1};
Arrays.sort(response); //Arrays.sort()
System.out.println(Arrays.toString(response));//Arrays.toString
System.out.println(Arrays.binarySearch(response,10));//Arrays.binarySearch()
//Arrays.copyOf(),生成长度为7的数组,并把response数组的值复制到demo,超出部分用默认值填充
int[] demo=Arrays.copyOf(response,7);
System.out.println(Arrays.toString(demo));
//Arrays.copyrange()生成一个新数组(指定范围)
int[] demo01=Arrays.copyOfRange(response,1,4);
System.out.println(Arrays.toString(demo01));
//Arrays.equals()
int[] array={1,3,9};
int[] array1={1,3,9};
System.out.println("是否指向同一内存:"+(array==array1));
System.out.println("是否相等:"+Arrays.equals(array,array1));
使用字符串进数据的处理
String
String类的常用操作
(1)计算字符串长度length()
方法获得字符串长度
(2)判断是否相同equals(Object anObject)
【不为null,类型都是String】
(3)获得指定位置的字符charAt(int index)
(4)返回字符串第一次出现的位置indexOf(String str)
(5)获的子字符串(截取字符串)substring(int beginIndex,int endIndex)
(6)拆分字符串split(String regex)
(7)怱略前导空白和尾部空白trim()
(8)替换旧字符串为新字符串replace(char oldChar,char newChar)
//lenght()
String str="谁偷了我的花裤衩";
System.out.println(str.length());
//equals()
String str1="谁偷了我的花裤衩";
String str2="谁偷了我的花裤衩";
String str3="18";
int num=18;
System.out.println(str1.equals(str2));
System.out.println(str1.equals(str3));
System.out.println(str3.equals(num));
//charAt()
System.out.println(str1.charAt(2));
System.out.println(str1.charAt(str1.length()-2));
//indexOf()
System.out.println(str1.indexOf("我的"));
//substring()
System.out.println(str1.substring(1,5));
//split()
System.out.println(str1.split("了")[0]);
//trim()
String str5=" 谁偷了我的花裤衩";
System.out.println(str5);
System.out.println(str5.trim());
//replace
System.out.println(str1.replace("我","你"));
StringBuffer
创建StringBuffer对象
(1)StringBuffer用于创建构造一个不包含字符串缓冲区,其初始字符是16个字符
StringBuffer sb=new StringBuffer();
(2)StringBuffer(String str),用干构造 一个符串缓冲区,并将其内䆟初始化为指定的字符串
StringBuffer sb = new StringBuffer("其实学学习也不错");
StringBuffer类的常用方法
(1)append(String str):用于将指定的字符串追加此字符序列
(2)insert(int offer,String str),用于将字符串插入字符串指定的位置
(3)reverse():用用将字符串进行反转
(4)delete(int start,int end)用于移除此字符序列指定区间
//append
String bookName="图书名称:Think in Java";
StringBuffer book = new StringBuffer("图书");
book.append(";");
book.append(bookName);
System.out.println(book);
StringBuffer contont=new StringBuffer("This is a day");
//insert
System.out.println(contont.insert(10,"nice"));
//reverse
System.out.println(contont.reverse().toString());
contont.reverse();
//delete
contont.delete(10,14);
System.out.println(contont);
使用集合/文件进行数据存储
集合
集合框架
-
为什么使用集合
- 如果并不知道程序运行时会需要多少对象,或者需要更复杂方式存储对象——可以使用Java集合框架 集合框架是一个用来代表和操纵集合的统一框架。所有集合框架都包含如下內容
- 接囗:是代表集合的抽象类型。接回允许集合独立操纵其代表的细节
- 实现(类):是集合接囗的体现。从本质上讲,它们可一重复使用数据结构
- 算法:是实现集合结囗的对象里的方法执行的一些有用的计算
-
几种重要集合和接囗类简介
-
(1)List集合代表一个元素有序,可重复的集合,集合中每个元素都有其对应的顺应的顺序索引。List集合允许使用重复元素,可以通过索引来访问指定的集合元素。List集合默认按元素的添加顺序设置元素 的索引。List的实现类有:
1).ArrayList类支持可随雪要而增长的动态数组。ArrayList类对于使用索引取出元索有较高的效率,它可以使用索引来快速定位对象。但对元素做删除或插入时速度较慢,因为使用数组,需要移动后面的元素来调整索引的顺序 2).LinkeLlist类提供了一个双向链表数据结构,所以针对频繁的插入和删除数据使用LinkedList类效率较高,它适合实现栈和队列
-
(2)Set集合类似于一个罐子,程序可以一次把对象丢进集合,而集合不能记住元素的添加顺序,并且没有重复对象。
Set接囗常用的三个实现类 1).Hashset类是Set使用较广泛,它不保存元素的加入顺序。HashSet类根据元素的哈希码进行存放,取出时也会也会根据哈希码快速找到 2).LinkedHashSet那根据元素的哈希码进行存放,同时用链表记录元素加入的顺序。通过链表来存储对象,一般插入和删除的效率较高,检索效率相对较低。 3).TreeSet类似用红黑树结构对加入的元素进行排序存放,通过TreeSet构造方法来获取TreeSet对象
-
(3) Map集合用于保存据有映射关系的数据,即一个存储关键字和值的关系或者说是关键字/值的对象
Map接囗常用的实现类 1).HashMap是基于哈希表的Map接口的实现。此实现提供所有可选的入市操作并允许null值和null键 2).TreeMap那基于红黑树的NavigableMap实现。该映射根据键的自然顺序进行排序,或者根据创䢖映射时提供的Comparator进行排序
Collection接囗方法
Collection接囗是List,Set和Queue接囗的父类囗,该接囗里提供了在集合中添加与删除元素的基本操作以及多种查询。
方法名 | 说明 |
---|---|
boolean add(Object o) | 在列表的末尾添加元素,起始元素从0开始 |
addAll(Collection<? extends E>e) | 将指定collection中的所有元素都添加到些collection中 |
int size() | 返回列表中元素个数 |
Object get(int index) | 返回指定索引位置处的元素。取出的元素是Object类型,使用前需要强制类型转换 |
boolean contains(Object o) | 判断集合中元素是否存在 |
boolean remove(Object o) | 从列表中删除元素 |
Object remove(int index) | 从列表中删除指定位置的元素,起始位置从0开始 |
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
public class CollecTion {
public static void main(String[] args) {
Collection c = new ArrayList();
//https://zhidao.baidu.com/question/86487960.html
//添家元素
c.add("java 讲义");
c.add("Linux");
c.add("水浒传");
c.add("10");
System.out.println(c);
//集合査找
System.out.println("c集合中元素的个数为:"+c.size());
System.out.println("c集合中是否包含Linux"+c.contains("Linux"));
//删除元素
c.remove("Linux");
System.out.println("c集合中元素的为:"+c);
Collection books=new HashSet();
books.add("Java 讲义");
books.add("平凡的世界");
//用C集合减去books集合里的元素
c.remove(books);
System.out.println("用C集合减去books集合里的元素的结果为"+c);
//把book中的元素添加到c中
c.addAll(books);
System.out.println("把book中的元素添加到c中后,c的元素为"+c);
//清空集合中的元素
c.clear();
System.out.println("清空后集合c中的元素为:"+c.size());
}
}
使用foreach遍历集合中的元素
foreach循环除了能便捷的访问数组的元素,也可以很方便地迭代访问集合中的元素
import java.util.ArrayList;
import java.util.Collection;
public class CollecTion {
public static void main(String[] args) {
Collection books = new ArrayList();
//添加元素
books.add("Think in Java");
books.add("Java 讲义");
books.add("Java语言程序设计");
books.add("疯狂Java讲意");
//遍历集合
System.out.println("书库中的书籍有:");
for (Object book:books){
System.out.println(book);
}
}
}
集合与泛型
(1)为什使用泛型
集合中保存的类型都是Object,从集合中取元素都需要强制类型转换,还有插入的时候没有错误检査,结果get强制转换的时候出现ClassCastException
,为解决这个问题,JDK1.5中支持一中新特性——泛型
(2)什么是泛型
所谓泛型是指在定义(类的定以,方法的定以,形参的定以,成员变量的定义等)的时候,指定它们的通用数据类型,也就是数据类型可以是任意的数据类型。具体调用的时候也要将通用数据类型转换为指定类型使用。
(3)在集合中使用泛型
基本语法
Collection<类型参数> 变量=new ArrayList<>();
ArrayList<数据类型> arr=new ArrayList<>()
ArrayList<数据类型> arr=new ArrayList<>(Collection)
import java.util.ArrayList;
/**
类中的方法:
构造方法:集合的构造方法:空构造方法,包含Collection集合的构造方法
方法:接口中的方法
属性的getter和setter
自身特有的
添加:
add:添加一个元素
和addAll:添加一个集合
包含:依据存储的数据类型是否重写了equals方法
contains
containsAll
删除 集合或元素
remove
removeAll
*/
public class CollectionDemo {
public static void main(String[] args) {
ArrayList<Integer> arr=new ArrayList();
ArrayList<String> arr1=new ArrayList<>();
arr1.add("java");
arr1.add("mysql");
arr1.add("html");
ArrayList<String> arr2=new ArrayList<>();
arr2.addAll(arr1);
/* System.out.println(arr1.size());
System.out.println(arr1.contains("mysql"));*/
arr1.remove("mysql");
System.out.println(arr2.containsAll(arr1));
arr2.removeAll(arr1);
System.out.println(arr2.size());
}
}
数据类型不能是内置的数据类型:byte short int long float double boolean char
用数据类型对应的包装类型:Byte Short Integer Long Float Double Boolean Character
总结(我老师的代码):
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import java.util.function.Consumer;
import java.util.function.Predicate;
/**
* List:有序的,get(i),重复的数据
* Set:无序的,不重复的数据
* 2、构造方法:
* new HashSet<>();
* new HashSet<>(Collection);
* 3、添加
* add
* addAll
* 4、删除:
* remove
* removeall:删除交集
* retainsAll:保留交集
* removeIf:按照条件删除
* 5、set集合大小 size()
* 6、判断set结合中是否包含某个元素或者子集合
* contains
* containsAll
* 7、集合的遍历
* Iterator迭代器遍历集合
* forEach语句
* forEach方法
*/
public class SetDame {
public static void main(String[] args) {
Set<Integer> set1=new HashSet<>();
//添加三个元素1,2,3,1,2,3
set1.add(1);
set1.add(2);
set1.add(3);
set1.add(1);
set1.add(2);
set1.add(3);
System.out.println("Set1 的值为");
set1.forEach(integer -> System.out.print(integer+" "));
System.out.println();
//问题:根据set1,创建set2
Set<Integer> set2=new HashSet<>();
set2.addAll(set1);
//删除:remove removeAll
set2.remove(1);
set2.add(4);
set2.add(5);
System.out.println();
set2.forEach(integer -> System.out.print(integer+" "));
//removeIf :删除满足条件的数据
/* set2.removeIf(new Predicate<Integer>() {
@Override
public boolean test(Integer integer) {
return integer%2!=0;
}
});*/
System.out.println();
set2.removeIf(integer ->integer%2!=0 );
set2.forEach(integer -> System.out.print(integer+" "));
/*System.out.println();
set1.removeAll(set2);
System.out.println("删除交集后的数据为:");
set1.forEach(integer -> System.out.print(integer+" "));*/
/* System.out.println("保留交集");
set1.retainAll(set2);
set1.forEach(integer -> System.out.print(integer+" "));*/
//遍历集合
//Iterator<Integer> it = set1.iterator();
// hasNext():判断是否有下一个元素
//next():取得下一个元素的值
/*while(it.hasNext()){
System.out.print(it.next()+" ");
}*/
//for(集合元素类型 变量:集合) 每次从集合中取出一个元素赋值给变量
/*for(Integer i:set1){
System.out.print(i+" ");
}*/
//forEach(Consumer)
/*set1.forEach(new Consumer<Integer>() {
@Override
public void accept(Integer integer) {
System.out.println(integer+" ");
}
});*/
/*
lambda 表达式:函数式接口->只有一个抽象方法的接口
可以根据参数个数自动推断参数的类型以及方法
格式:(参数列表)->{方法体}
参数列表中参数的类型可以省略,但是参数的个数必须与函数式接口中参数的个数一致
如果参数的个数只有一个,那么()可以省略
参数->{}
()->{}
方法体中,只有一句话
(参数列表)->表达式
函数式接口:
Comparator<T,T>:定义一个比较器
Consumer<T> void accept(T t):接受一个参数,进行操作,没有返回值
Supplier<T> 接受一个参数,进行操作,有返回值
*/
}
}
Map接囗和HashMap类
Map接中常用的方法
方法名 | 说明 |
---|---|
Object put(Object key,Object value) | 插入新的对象,并用key作为其关键字 |
void putAll(Map t) | 将叧一个Map中的所有对象复制出来 |
Set entrySet() | 返回关映射中的键字-值对的集合 |
Set keySet() | 返回映射中所有关键字的集合 |
collection values() | 返回映射中所有值的集合 |
Object remove(Object key) | 删除指定对象 |
Object get(Object key) | 获取与key相联系的对象 |
boolean containsKey(Object key) | 判断是否包含指定的键值 |
BooleancontainsValues(Object value) | 判断是否包含指定的对象 |
import java.util.HashMap;
import java.util.Map;
public class CollecTion {
public static void main(String[] args) {
//创建map对象,map内没有任何对象
Map<String,String> map=new HashMap();
//添加元素 对象名.put(key,value);
map.put("01","Think in java");
map.put("02","java 讲以");
map.put("03","java 语言设计");
map.put("04","疯狂java讲义");
//添加元素如果没有(key:value)就添加 对象名.putIfAbsent(key,value)
map.putIfAbsent("03","MySQL数据库");
map.putIfAbsent("05","大数据处理");
System.out.println(map.get("03"));
System.out.println(map.get("05"));
//获得value值 对象名.get(key)
System.out.println(map.get("03"));
//删除元素
map.remove("03");
System.out.println("集合是否包含\"java语言程序设计\","+map.containsValue("java语言程序设计"));
//修改元素的值,put没有(key)是添加,有的话是修改 对象名.put(key,value);
map.put("02","平凡的世界");
System.out.println("集合是否包含\"java讲义\","+map.containsValue("java讲义"));
//获取集合的元素 对象名.get(key)
System.out.println("编号02的名称"+map.get("02"));
//创建demo01对象类型是HashMap,并且传入map
Map<String,String> demo01=new HashMap<>(map);
Map<String,String> demo02=new HashMap<>();
demo02.putAll(map);
System.out.println(demo02.size());
//删除:删除某一个key值 对象名.remove(key);
demo01.remove("01");
//删除:删除所有的元素 对象名.clear();
demo02.clear();
//打印demo02的大小 demo02.size()
System.out.println("demo02的大小为"+demo02.size());
}
}
遍历map集合
1.以Set方式遍历
keySet
Map.entry<K,V>
2、调用函数forEach
3、Stream(List,Set,Map) 1.8
(1.1) .KeySet()方法返回映射中所有关键字的Set集合。迭代键值Set,通过Map接囗的get(key)方法,获取每一个键对应的值
(1.1.1). forEach 语句
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
public class MapPL {
public static void main(String[] args) {
Map<String,String> map = new HashMap<>();
map.put("01","Think in java");
map.put("02","java 讲以");
map.put("03","java 语言设计");
map.put("04","疯狂java讲义");
//1.1 获得key的set视图
Set<String> keys = map.keySet();
//1.2、遍历keyset,获得每个key,调用get方法获得value的值
for (String key:keys){
System.out.println(map.get(key));
}
}
}
(1.2.2). Iterator
方法 | 含意 |
---|---|
boolean hasNext | 如果仍有元素可以迭代则返回true |
Object next() | 返回迭代的下一个元素 |
void remove | 从迭代器指向的collection中移除迭代器返回的最后一个元素 |
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
public class MapPL {
public static void main(String[] args) {
Map<String,String> map = new HashMap<>();
map.put("01","Think in java");
map.put("02","java 讲以");
map.put("03","java 语言设计");
map.put("04","疯狂java讲义");
//获得key的set视图
Set<String> keys=map.keySet();
//遍历keyset,获得每个key,调用get方法获得value的值
//Iterator迭代器遍历
Iterator<String> it = keys.iterator();
while(it.hasNext()) {// 对象名.hasNext() 判断是否有下一个key(判断集合里是不是已经没有元素了),返回值为true和false
String key=it.next(); // 对象名.next() 就是取得当前集合的元素 然后把指针往后移一位指向下一个元素
System.out.println(key+"对应的值为:"+map.get(key));
}
}
}
(1.1.3) lambda表达式
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
public class MapPL {
public static void main(String[] args) {
Map<String,String> map = new HashMap<>();
map.put("01","Think in java");
map.put("02","java 讲以");
map.put("03","java 语言设计");
map.put("04","疯狂java讲义");
//获得key的set视图
Set<String> keys=map.keySet();
//1.2.3 forEach函数:lambda表达式-->函数式接口
keys.forEach(key->System.out.println(key+":"+map.get(key)));
}
}
(1.2) .方法entrySet()
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
public class CollecTion {
public static void main(String[] args) {
Map<String,String> map=new HashMap();
//添加元素
map.put("01","Think in java");
map.put("02","java 讲以");
map.put("03","java 语言设计");
map.put("04","疯狂java讲义");
//2、把map 中的key和value看作是一个元素 Map.entry<key,value>
//Map.entry 有两个方法,getKey,getValue
Set<Map.Entry<String, String>> entries = map.entrySet();
for(Map.Entry<String, String> entry:entries){
System.out.println(entry.getKey()+":"+entry.getValue());
}
}
}
文件操作
File类
构建File类
1是相对路径,2是绝对路径
(1)new File(String pathname),pathname是路径,通过给定的路径创建一个新的File实例
File fs = new File("test.txt");//枏对路径
(2)new File(File parent,String child)。完整的路径parent.getPath()+child
File dir = new File("E:\\Java\\Demo\\src");
File file= new File(dir,"test.txt");
(3)new File(String parent,String child),完整的路径parent+child
File file= new File("E:\\Java\\Demo\\src","test.txt");
File类方法
import java.io.File;
public class fileDemo {
public static void main(String[] args) {
File file= new File("E:\\Java\\Demo\\src","test.txt");//证明一下
// 注释 代码
System.out.println("判断文件是否存在"+file.exists());
System.out.println("读取文件名称"+file.getName());
System.out.println("读取文件目录"+file.getPath());
System.out.println("读取文件的绝对目录"+file.getAbsolutePath());
System.out.println("读取文件的父级目录"+new File(file.getAbsolutePath()).getPath());
System.out.println("读取文件的大小"+file.length()+"byte");
System.out.println("读取文件是否隐藏"+file.isHidden());
System.out.println("判断文件是否可读"+file.canRead());
System.out.println("判断文件是否可写"+file.canWrite());
System.out.println("判断文件是否为文件夹"+file.isDirectory());
}
}
/**
Map存储的数据都是以key和value方式存储,而且key是唯一的 MapReduce
Redis 内存数据库,key value
一、添加元素
put(key,value)
putIfAbsent
get(key)
getDefault
remove(key)
clear
二、map的遍历
1.以Set方式遍历
keySet
Map.entry<K,V>
2、调用函数forEach
3、Stream(List,Set,Map) 1.8
*/
IO流
数据流:是指一组有排序的有起点的的字节集合。它包括输入流和输出流。将数据从外存中读到内存中的称为输入流,将数据从内存写入外存中的称为输出流。
字符流字节流
(1)字节流:数据流中的最小的数据单元是字节
(2)字符流:数据流中的最小的数据单元是字符(一字符占二字节)
使用数据流的目的是,使程序的输入和输出操作独立于相关设备,使得程序能够用于多种I/O设备,不需要对源代码设置目标代码做任何修改,从而增强程序的可移植性
二进制I/O和文本I/O
FileInputStream类常用方法:
此类用于从本地文件系统中读取文件内容
方法名 | 说明 |
---|---|
int read(byte[] b) | 读取文件中的数据,将读到的数据存放到byte型数组中,并返回读取的字节的数量,未读到数据返回-1,有可能抛异常,必须捕捉 |
int read() | 读取文件中的数据,一次读取一个字节,读取的数据作为返回值返回,如果读到文件末尾则返回-1,有可能抛异常,必须捕捉 |
void close() | 关闭流对象,有可能抛异常,必须捕捉 |
读取文件
@Test
public void testReader() throws IOException {
//1 建立文件流对象
//右键文件名
//try with resource 自动资源回收
try (FileInputStream fis = new FileInputStream("user.csv");) {
//2 读取内容
int hasRead = 0;//读取的字节的长度
byte[] bytes = new byte[512];//存放读取的数据
while ((hasRead = fis.read(bytes)) != -1) {
System.out.println(new String(bytes, 0, hasRead));
}
}
//3 关闭流
//fis.close();
}
FileOutputStream
FileOutputStream类称为文件输出流,继承于OutputStream类,是进行文件写操作的最基本类;
它的作用是将内存中的数据输出到文件中,我们可以利用它来写文件
FileOutputStream类常用方法
方 法 原 型 | 说 明 |
---|---|
void write(int b) throws IOException | 往文件中写数据,一次写一个字节,有可能抛异常,必须捕捉。 |
void write(byte[] b) throws IOException | 往文件中写数据,将byte数组中的数据全部写入到文件中。 |
void close() throws IOException | 关闭流对象 |
void flush( ) | 强制输出 |
void write(byte b[], int off, int len) | 从给定字节数组中起始于偏移量off处写len个字节到输出流。 |
文件的写入
@Test
public void outputFile() throws IOException {
//两个构造参数:文件对象或文件的地址
// 写入方式,true追加,false 覆盖
//1 创建流对象
FileOutputStream fos = new FileOutputStream("user.csv");
//2 写入
fos.write("zs,123,zhangsan".getBytes());
fos.write('\n');
fos.write("ls,123456,lisi".getBytes());
//关闭实体,流释放资源
fos.close();
}
-
装饰流
- 1.按照流是否直接连接实际数据源,将流划分为实体流和装饰流两大类。
- 2.实体流(节点流)指直接连接数据源的流类,如FileReader和FileWriter,实体流类均可单独进行使用。
- 3.装饰流(处理流)指不直接连接数据源,而是以其它流对象(实体流对象或装饰流对象)为基础建立的流:类。
- 4.比较常用的有DataInputStream/DataOutputStream和BufferedReader/BufferedWriter等。
- 5.装饰流类不可以单独使用,必须配合实体流或装饰流使用。
- 6.装饰流不改变原来实体流对象中的数据内容,只是从实体流对象基础上创建出的装饰流对象相对于实体流对象进行了一些功能的增强。
- 例如:使读写的速度增加或者提供更多的读写方式,方便数据格式的处理 缓冲流:BufferedInputStream和BufferedOutputStream
- 1.缓冲流BufferedInputStream和 BufferedOutputStream类操作数据时,需要先将数据读写到缓冲区中,这样可以提高文件流的操作效率。
- 2.这两个类在数据流上增加了一个缓冲区,当读写数据时,数据以块为单位,先进入缓冲区,其后的操作则作用于缓冲区
- 3.当写满缓冲区或关闭输出流时,一次性输出到流,或者用flush()方法主动将缓冲区输出到流
@Test
public void bufferReadFile() throws IOException {
//1 建立文件流对象
//缓冲流,在实体流的基础上,建立缓冲流(装饰流)
//try with resource 自动资源回收
try (FileInputStream fis = new FileInputStream("user.csv");
BufferedInputStream bis = new BufferedInputStream(fis);) {
//2 读取内容
int hasRead = 0;//读取的字节的长度
byte[] bytes = new byte[512];//存放读取的数据
while ((hasRead = bis.read(bytes)) != -1) {
System.out.println(new String(bytes, 0, hasRead));
}
}
//bis.close();
}
-
字符流
- 由于Java采用16位的Unicode字符,因此需要基于字符的输入/输出操作。
- Reader和Writer这两个抽象类主要用来读写字符流。
- 注意: Reader和Writer只是提供一些用于字符流的接口,本身不能用来生成对象。
Reader类
方法 | 说明 |
---|---|
boolean ready() | 输入字符流是否可读 |
int read() | 读取一个字符 |
int read(char[] cbuf) throws IOException | 读取一串字符(到字符数组cbuf) |
long skip(long n) | 跳过n个字符 |
mark(int readAheadLimit) | 在当前位置做一标记 |
reset() | 将读取位置恢复到标记处 |
close() | 关闭字符流 |
FileReader类
构造方法 | 说明 |
---|---|
FileReader(File file) throws FileNotFoundException | 使用File对象创建文件输入流对象,如果文件打开失败,将抛出异常 |
FileReader(String name) throws FileNotFoundException | 使用文件名或路径创建文件输入流对象,如果文件打开失败,将抛出异常 |
Writer类
方法 | 说明 |
---|---|
void close() | 关闭流 |
void flush() | 强行写入 |
void write(int c) throws IOException | 写入c |
void write(char[] cbuf) throws IOException | 写入字符数组cbuf |
void write(char[] cbuf, int off, int len) throws IOException | 写入字符数组cbuf中自位置off开始的len个字符 |
void write(String str) throws IOException | 写入字符串str |
void write(String str, int off, int len) throws IOException | 写入字符串str中自位置off开始的len个字符 |
FileWriter构造方法
构造方法 | 说明 |
---|---|
FileWriter(File file) throws IOException | 使用File对象创建文件输出流对象,如果文件打开失败,将抛出异常,必须捕捉 |
FileWriter(File file, boolean append) throws IOException | 使用File对象创建文件输出流对象,并由参数append指定是否追加,异常情况同上 |
FileWriter(String name) throws IOException | 直接使用文件名或路径创建文件输出流对象,异常情况同上 |
FileWriter(String name, boolean append) throws IOException | 直接使用文件名或路径创建文件输出流对象,并由参数append指定是否追加,异常情况同上 |
@Test
public void fileReader() throws IOException {
//字符流,以字符为单位处理文件
FileReader fr=new FileReader("user.csv");
//2 读
char[] chars=new char[512];
int hasRead=0;
while((hasRead=fr.read(chars))!=-1){
System.out.println(new String(chars,0,hasRead));
}
//3.关闭流
fr.close();
}
@Test
public void charBufferReader() throws IOException {
//字符流,以字符为单位处理文件
FileReader fr=new FileReader("user.csv");
BufferedReader br=new BufferedReader(fr);
//2 读
while(br.ready()){
String line = br.readLine();
String[] strs = line.split(",");
System.out.println(strs[2]);
}
//3.关闭流
br.close();
}