类名要和文件名保持一致
public class ht {
public static void main(String[] args){
System.out.println("Hello World");
}
}
C:\Users\zhangjinzhong\Desktop\java>javac ht.java
C:\Users\zhangjinzhong\Desktop\java>java ht
数据类型
Java 提供了八种原始数据类型:
- 数值型:byte、short、int、long、float、double
- 字符型:char
- 布尔型:boolean
基本数据类型
数值型:
整型:byte、short、int、long
浮点型:float、double
字符型:char
布尔型:boolean
引用数据类型(内存操作)
数组、类、接口
但是对于以上给出的基本数据类型的定义,如果从实际的开发角度上,以下的几种类型最为常用:
· int型:只要是看见了整型的定义,其类型都是int;
· double型:只要是看见了小数的定义,其类型都是double;
· byte型:日后进行数据传输的时候使用此类型,讲解到IO,和编码转换的操作上使用;
· boolean:用于程序的逻辑操作使用;
· long:表示日期时间、表示文件长度的时候。
int age = 30;
double salary = 5000.50;
boolean isEmployed = true;
引用数据类型
包括类、接口、数组和枚举等。引用类型的变量存储对象的内存地址。
String name = "Alice";
int[] numbers = {1, 2, 3, 4, 5};
数组
初始化
// 直接初始化
int[] numbers = {1, 2, 3, 4, 5}; // 定义并初始化数组
// 定义后赋值
int[] moreNumbers = new int[5]; // 创建一个长度为5的数组
moreNumbers[0] = 10; // 赋值
moreNumbers[1] = 20;
moreNumbers[2] = 30;
moreNumbers[3] = 40;
moreNumbers[4] = 50;
// 访问数组元素
int firstNumber = numbers[0]; // 获取第一个元素
数组排序
import java.util.Arrays; // 导入Arrays类
public static void main(String[] args) {
int[] numbers = {5, 2, 8, 1, 3}; // 初始化数组
Arrays.sort(numbers); // 对数组进行排序
System.out.println(Arrays.toString(numbers)); // 打印排序后的数组
}
数组复制
int[] original = {1, 2, 3, 4, 5};
int[] copy = Arrays.copyOf(original, original.length); // 复制数组 复制的数组,复制几位
System.out.println(Arrays.toString(copy)); // 输出复制的数组
多维数组
// 定义一个二维数组
int[][] matrix = new int[3][4]; // 3行4列的二维数组
// 初始化一个二维数组
int[][] matrix2 = {
{1, 2, 3, 4},
{5, 6, 7, 8},
{9, 10, 11, 12}
};
//访问
int value = matrix2[1][2]; // 获取第二行第三列的元素
System.out.println(value); // 输出: 7
//遍历
for (int i = 0; i < matrix2.length; i++) { // 外层循环遍历每一行
for (int j = 0; j < matrix2[i].length; j++) { // 内层循环遍历当前行的每一列
System.out.print(matrix2[i][j] + " "); // 打印当前元素
}
System.out.println(); // 在每行结束后换行
}
数组的优缺点 1 优点
存储相同类型的数据:数组允许我们将相同类型的数据存储在一起。
快速访问:通过索引,可以快速访问和修改数组中的元素。
内存连续性:数组在内存中是连续存储的,访问速度较快。
2 缺点
固定大小:一旦定义,数组的大小就无法更改。
内存浪费:如果数组分配的大小大于实际使用的元素数量,会导致内存浪费。
操作不便:插入和删除元素的效率较低,尤其是在大数组中。
定义变量(标识符)或方法的时候也有一个明确的要求:第一个单词的首字母小写,之后每个单词的首字母大写,例如:studentName。而在定义类名称的时候(标识符),每一个单词的首字母大写,例如:TestDemo。
switch
// 猜拳游戏: 1-石头,2-剪刀,3-布
int i = 1;
String str;
switch (i) {
case 1:
str = "石头";
break;
case 2:
str = "剪刀";
break;
case 3:
str = "布";
break;
default:
str = "其他";
break;
}
System.out.println("你出的是:" + str);
// 简写
String str = switch (i) {
case 1 -> "石头";
case 2 -> "剪刀";
case 3 -> "布";
default -> "其他";
};
循环
知道具体的循环次数,优先使用for循环
while是先判断循环条件,在执行循环体
do...while是执行一次的循环体,在判断循环条件
do...while至少会执行一次
while循环
int i = 1;
while (i <= 20) {
System.out.println("好好学习天天向上,第" + i + "遍");
i++;
}
// 打印1-10
int i = 0; // 变量初始化
while (i < 10) { // 循环条件
i++; // 变量改变
System.out.println(i);
}
do...while 循环
Scanner scanner = new Scanner(System.in);
String res;
do {
System.out.println("学习了java");
System.out.println("请老师检查是否合格:");
res = scanner.next();
}while ("n".equals(res));
System.out.println("今日学习圆满!");
// 打印1-10
int i = 0; // 变量初始化
do {
i++; // 变量改变
System.out.println("do...while 循环打印:" + i);
}while (i < 10); // 循环条件
** for 循环**
Scanner scanner = new Scanner(System.in);
System.out.print("请输入一个值:");
int num = scanner.nextInt();
for (int i = 0, j = num; i <= num; i++, j--) {
System.out.println(i + "+" + j + "=" + num);
}
//**循环输入某同学期末考试的5门课成绩,并计算平均分。**
Scanner scanner = new Scanner(System.in);
System.out.println("请输入考评者的名字:");
String name = scanner.next();
int sum = 0;
for (int i = 1; i <= 5; i++) {
System.out.println("请输入第" + i + "门功课的成绩:");
int grade = scanner.nextInt();
sum += grade;
}
int avaGrade = sum / 5;
System.out.println(name + "平均成绩是:" + avaGrade);
// 打印1-10
for (int i = 1; i <= 10; i++) {
System.out.println("for 循环打印:" + i);
}
-
while 循环:先判断再执行
-
do-while 循环:先执行再判断。初始情况不满足循环条件时,do-while 至少也会执行一次。
-
for 循环:先判断再执行
项目 模块 包 类
-
项目(Project):
项目是最大的组织单位,通常代表一个完整的软件应用或一组相关的应用。一个项目可以包含多个模块,这些模块可能属于同一个应用的不同部分,或者构成一个应用的不同功能。 -
模块(Module):
模块是项目中的一个独立部分,它有自己的编译和运行属性。在Java中,模块的概念从Java 9开始引入,每一个模块都有自己的module-info.java文件来定义模块的属性和依赖。模块可以理解为一个独立的单元,有自己的作用域,可以包含多个包。 -
包(Package):
包是模块内部的划分,用于组织类和接口。它是类和接口的容器,提供了一种方式来命名和访问类。一个包中可以包含多个类和接口,它们通常具有相似的属性或功能。例如,所有的用户界面相关的类可以放在一个叫做com.example.ui的包中。 -
类(Class):
类是面向对象编程的基本单元,它包含对象的属性和行为。类可以继承其他类,实现接口,并可以包含抽象方法或具体方法。在Java中,每一个文件通常对应一个公开的类,这个类与文件名相同。 -
接口(Interface):
接口是一种完全抽象的类,它不能包含任何具体方法的实现,但是可以包含抽象方法。一个类可以实现多个接口,表明该类遵循接口中声明的抽象方法。接口定义了一种约定,规定了实现接口的类应遵循的规则。 -
bean:存放 JavaBean 类,通常被用来封装数据,如模型类。 -
dao:存放数据访问对象(Data Access Objects),这些类负责与数据库进行交互,执行增删改查等操作。 -
service:存放业务逻辑代码,处理业务流程。 -
controller:存放控制器类,负责处理 HTTP 请求,将请求转发到其他模块处理。
类
- javabean 类:用来描述一类事物的类,eg: Student , Animal
- 测试类: 用来检查其他类是否书写正确的,带有main 方法的类,是程序的入口
- 工具类:不是用来描述一类事物的,而是帮我们做一些事情的类
类名见名之意 私有化构造方法,不让创建它的对象 方法定义为静态
public class ArrUtil {
private ArrUtil(){}
public static int getMax(){ return 1;};
public static int getMin(){ return 1;};
public static int getMum(){ return 1;};
public static int getAvg(){ return 1;};
}
包的概念
- 包的作用?
包就是文件夹,用来管理各种不同功能的java类
- 包名的书写规则?
公司域名反写+包的作用,需要全部英文小写,见名知意
- 什么是全类名?
包名+类名
- 什么时候需要导入包,什么时候不需要?
- 使用同一个包中的类时,不需要导入包
- 使用java.lang包中的类时,不需要导包
- 其他情况都需要导入包
- 如果同时使用两个包中的同名类,需要用全类名
为了更好的管理类,把多个类收集在一起称为一组称之为软件包。
* 在文件的最上方加上一个package语句指定该代码在哪个包中
对象
面向对象三大特性,封装、继承和多态
封装
将数据和操作数据的方法进行有机结合,隐藏对象的属性和实现细节,仅对外公开接口和对象进行交互。也就是对类内部的实现细节进行了隐藏(封装)对外只提供一些公开的接口,供其他用户进行访问。
- private:只能在当前类中访问
- default:在同一个包中的类可以访问,是默认权限
- protected:主要在继承中使用,可以被子类访问
- public:任何地方的类都可以使用
继承 (inheritance )
是面向对象的另外一个基本概念,利用继承,可以基于已存在的类构造一个新类。继承已存在的类就是复用这些类的方法和属性。在此基础上还可以添加一些新的方法和属性以满足新的需求。通过继承,可以达到对重复代码复用,减少代码量。 共性的抽取,实现代码复用。
- 构造方法不能继承
- 成员变量 public 和private 都能继承(private 不能直接使用)
- 成员方法 public 可以继承 private 不能继承
虚方法表
继承时,把这些方法放到了虚方法表中了
非private
非static
非final
在子类中可以直接使用父类的成员变量,当子类中存在与父类相同的成员变量时优先访问自己的成员变量,成员变量访问遵循就近原则,自己有就优先访问自己的,如果没则在父类中找,如果父类中也没有就会编译报错。
super关键字
在编写代码时,由于设计不好,或者场景需求,子类和父类中可能会存在相同名称的成员,如果要在子类方法中访问父类同名成员时,直接访问是无法做到的,在Java中提供了super关键字,可以在子类方法中访问父类成员。
super关键字只能在非静态方法中使用,在子类中访问父类的成员变量和方法。
super与this:
相同点: 都是java中的关键子;
只能在非静态方法中使用,用于访问非静态成员方法和属性;
在构造方法中调用时必须是构造方法的第一条语句,因此不能同时存在
不同点: this是当前对象的引用,而super则是相当于子类对象中从父类继承下来的部分成员的引用。
在非静态成员方法中,this用来访问本类的方法和属性,super用来访问父类的继承下来的方法和属性。
在构造方法中,this()用于调用本类的构造方法,super()用于调用父类的构造方法,两种调用不能同时存在,因为这两种调用都必须四构造方法的第一条语句。
构造方法中一定会存在super()的调用,哪怕没有写,编译器也会自行添加,而this()则不会。
3.2.3子类的构造方法
子类对象构造时,需要先调用父类构造方法,然后执行子类构造方法
class SuperClass{
int a = 1;
public void methob1(){
System.out.println("父类中的mothob1()方法");
}
}
class SubClass extends SuperClass{
int a = 2;
//`@Override`注解是一个元数据(metadata),它告诉编译器你打算重写父类中的一个方法。
//当你在子类中写了一个方法,并且希望这个方法覆盖(重写)父类中的同名方法时,
//你可以在这个方法上使用`@Override`注解。
@Override
public void methob1() {
System.out.println("子类中的mothob1()方法");
}
{
System.out.println(a);
System.out.println(super.a);
methob1();
super.methob1();
}
}
public class Animal {
String name;
int age;
float weight;
public void eat() {
System.out.println(name + "正在吃饭");
}
public void sleep() {
System.out.println(name + "正在睡觉");
}
}
public class Cat extends Animal{
void mew() {
System.out.println(name + "喵喵喵");
}
public void catchMouse(){
System.out.println(name + "正在抓老鼠");
}
}
public class Dog extends Animal{
void Bark() {
System.out.println(name + "汪汪汪");
}
public void lookDoor(){
System.out.println(name + "在看门");
}
}
就近原则
先在局部位置找->本类成员位置找->父类成员位置找,逐级往上
public class GoodInfo {
public static void main(String[] args) {
Zi z = new Zi();
z.show();
}
}
class Ye{
String name ="ye";
}
class Fu extends Ye {
String name ="fu";
}
class Zi extends Fu {
String name ="zi";
public void show(){
String name = "showName";
System.out.println(name); //showName
System.out.println(this.name); //zi
System.out.println(super.name); //fu
//就近原则,都能打印
System.out.println(color); //yellow
System.out.println(this.color); //yellow
System.out.println(super.color); //yellow
}
多态
什么是多态?
对象的多种形态
多态的前提
有继承/实现关系
有父类引用指向子类对象
有方法的重写
多态的好处
使用父类型作为参数可以接收所有子类对象,体现了多态的扩展性和便利
创建对象(多态方式)
// Fu f = new Zi()
f.name //拿到的是Fu中的name
调用成员变量:编译看左边,运行也看左边
编译看左边:javac 编译代码的时候会看左边父类中有没有这变量,如果有编译成功,否则失败
运行也看左边:java 运行代码的时候,实际获取的就是左边父类中成员变量的值
调用成员方法:编译看左边,运行看右边
编译看左边:javac 编译代码的时候会看左边父类中有没有这个方法,如果有编译成功,否则失败
运行看右边:java 运行代码的时候,实际运行的是子类中的方法
因为子类对父类的方法进行了重写
多态的弊端,不能调用子类的特有的方法
比如下方的 Dog特有的eat方法,就调用不了,因为 编译看左边,运行看右边,编译的时候区Ani父类中去查找,父类中没有eat方法,就会直接报错了
解决方案:
//变回子类型
Dog d = (Dog) a
d.eat()
实例:
class Ani{
String name = "动物";
public void show() {
System.out.println(this.name);
}
}
class Dog extends Ani{
String name = "狗";
@Override
public void show() {
System.out.println(this.name);
}
public void eat(){
System.out.println("狗在吃骨头")
}
}
public class Animal{
public static void main(String[] args) {
Ani a = new Dog();
System.out.println(a.name); //动物
a.show(); //狗
}
}
也就是下边所说的向上转型和向下转型
多态通俗来讲,就是多种形态,具体点就是去完成某个行为,当不同的对象去完成时会产生出不同的状态。 以动物为例,同样都是吃,狼吃肉,羊吃草这便是多态,总的来说就是同一件事,发生在不同对象身上就会产生不同的结果
多态的实现条件
在Java中要实现多态,就必须在继承体系下,且子类必须对父类中的方法进行重写,并且可以通过父类的引用调用重写的方法 多态体现: 在代码运行时,当传递不同类对象时,会调用对应类中的方法
重写
重写(Override)是指的是子类对父类中已有的方法重新实现。在重写过程中,子类需要按照和父类相同的方法签名(即方法名、参数列表)来定义自己的方法体,可以在方法体中重新定制适合子类的具体实现。
重写的前提是父类方法必须是非静态、非私有、非final修饰和非构造的方法。因为静态方法是与类关联而不是对象,私有方法不能被子类访问,而final修饰的方法被称为密封方法是不可重写的。
重写的好处在于子类可以根据自身的特定需求来定义特定的行为,即子类能够根据需要实现父类的方法。这样可以提供更灵活和多样化的功能。同时,通过重写,子类可以修改和优化父类的行为,实现代码的复用和扩展。
向上转型和向下转型
向上转型
向上转型,JAVA中的一种调用方式。向上转型是对父类的对象的方法的扩充,即
父类的对象可访问子类从父类中继承来的和子类重写父类的方法。
向上转型后, 不能使用原来子类中特有的字段,和方法
语法格式:父类类型 对象名 = new 子类对象
class Animal {
String name;
int age;
public Animal(String name, int age) {
this.name = name;
this.age = age;
};
public void say() {
System.out.println("animal say" + name);
};
public void eat() {
System.out.println("animal eat");
}
};
class Dog extends Animal {
public Dog (String name, int age) {
super(name, age);
}
public void say() {
System.out.println("dog say" + name);
}
public void colorGet() {
say();
super.say();
}
}
public class ExtendsClass {
public static void main(String[] args) {
Animal dd = new Dog("小黑",3); //向上转型的声明
dd.say(); //dog say小黑,访问的是 子类的say
dd.eat(); //可以访问父类的方法
dd.colorGet();
//会报错,colorGet 是子类特有的方法,只能访问子类从父类中继承来的和子类重写父类的方法
}
}
//**向上转型的优点:** 让代码实现更简单灵活
//**向上转型的缺点:** 不能调用子类特有的方法
向下转型
将一个子类对象经过向上转型之后当成父类方法使用,再无法调用子类的方法,但有时候可能需要调用子类特有的方法,此时:将父类引用再还原为子类对象即可,即向下转型。
Animal animal1 = dd;
if(animal1 instanceof Dog){//判断是否可以安全转换
dd = (Dog)animal1;
dd.lookDoor();
}
内部类
在一个类的里面再定义一个类
当一个事务的内部,还有一个部分需要一个完整的结构进行描述,而这个内部的完整的结构由只为外部事务提供服务,那么此时可以考虑使用内部类。内部类可以访问外部类的所有成员,包括私有成员,从而方便地为外部事务提供服务。
内部类是Java中一种特殊的类定义方式,它可以被定义在其他类或者方法的内部。内部类也是封装的一种体现,可以被用来实现一个类的私有成员或者私有方法。内部类只有在外部类中是可见的,对外是不可见的,从而实现了隐藏和封装的效果。
总的来说,内部类在Java中是一种实现封装和提供服务的机制,可以将一个事务的内部结构完整地描述出来,同时也增强了代码的可读性和可维护性。
- 成员内部类(Member Inner Class)
- 局部内部类(Local Inner Class)
- 匿名内部类(Anonymous Inner Class)
- 静态内部类(Static Inner Class)
class OutClass{
int a = 1;
static int b = 2;
String e = "外部类";
//实例内部类
class InClass{
int c = 3;
static final int d = 4;//常量
String e = "实例内部类";
public void print(){
System.out.println(a);
System.out.println(b);
System.out.println(c);
System.out.println(d);
System.out.println(e);
System.out.println(OutClass.this.e);
}
}
}
public class Test {
public static void main(String[] args) {
//1、创建外部类对象
OutClass outClass = new OutClass();
//2、创建内部类对象
OutClass.InClass inClass = outClass.new InClass();
inClass.print();
}
}
抽象类
1、抽象类的作用是什么样的?
- 抽取共性时,有一些共性无法确定方法体,就把方法定义为抽象类
- 强制让子类按照某种格式重写
- 抽象方法所在的类,必须是抽象类
2、抽象类和抽象方法的格式?
public abstract 返回值类型 方法名(参数列表)
public abstract class 类名 {}
3、继承抽象类有哪些要注意的?
继承的class 要么重写抽象类中的所有的抽象方法,要么 也是一个抽象类
在Java中如果一个类被abstract修饰则被称为抽象类,抽象类中被abstract修饰的方法称为抽象方法,抽象方法不用给出具体的实现体。抽象类也是类内部可以包含普通方法和属性构造方法。
抽象类代表着没有人可以创建出该类的实例,它除了被继承以外,是没有用途,没有值,没有目的的
public abstract class Shape {
double a;
abstract public void draw();
abstract public void colour();
}
抽象类的特性
1、使用abstract修饰的类就是抽象类
2、抽象类当中可以包含普通类所能包含的成员
3、抽象类和普通类不同的是可以包含抽象方法
4、抽象方法是使用abstract修饰的这个方法没有具体实现
5、抽象类不能被实例化
接口
接口就是一种规则,是对行为的抽象
接口中成员的特点:
成员变量:
只能值常量
默认修饰符: public static final
构造方法:没有
成员方法:
jdk7以前只能 有 抽象方法,默认修饰符:public abstract
jdk8新特性:接口中可以定义有方法体的方法
jdk9新特性:接口中可以定义私有方法
构造方法
- 构造方法的名字要与类名相同;
- 没有返回值;
- 创建对象时编译器自动调用,并且在对象的生命周期内只调用一次;
- 构造方法可以重载;
class Date {
public int year;
public int month;
public int day;
public Date(int year, int month) {
System.out.println("带两个参数的构造方法");
this.year = year;
this.month = month;
}
public Date(int year, int month, int day) {
System.out.println("带三个参数的构造方法");
this.year = year;
this.month = month;
this.day = day;
}
public void printDate(){
System.out.println(this.year+"-"+this.month+"-"+this.day);
}
}
public class Test {
public static void main(String[] args) {
Date d1 = new Date(2023,9,27);
Date d2 = new Date(2023,9);
d1.printDate();
d2.printDate();
}
}
// 定义一个简单的类:Person
public class People {
//成员变量
private String name;
private int age;
//构造器 可以重载 这里类似于设置默认值
//构造方法中可以通过this调用其他构造方法,this()必须为构造方法的第一条语句。
public People() {
this("张三", 18);
}
//构造器
public People(String name, int age) {
this.name = name;
this.age = age;
}
// 成员方法
public void say() {
System.out.println("我是" + this.name + "今年" + this.age + "岁");
}
public static void main(String[] args) {
People p1 = new People("里斯",20);
People p2 = new People();
p1.say(); //我是里斯今年20岁
p2.say(); //我是张三今年18岁
}
}
修饰符
类修饰符:
public(访问控制符),将一个类声明为公共类,他可以被任何对象访问,一个程序的主类必须是公共类。
abstract,将一个类声明为抽象类,没有实现的方法,需要子类提供方法实现。
final,将一个类生命为最终(即非继承类),表示他不能被其他类继承。
friendly,默认的修饰符,只有在相同包中的对象才能使用这样的类。
成员变量修饰符:
public(公共访问控制符),指定该变量为公共的,他可以被任何对象的方法访问。
private(私有访问控制符)指定该变量只允许自己的类的方法访问,其他任何类(包括子类)中的方法均不能访问。
protected(保护访问控制符)指定该变量可以别被自己的类和子类访问。在子类中可以覆盖此变量。
friendly ,在同一个包中的类可以访问,其他包中的类不能访问。
final,最终修饰符,指定此变量的值不能变。
static(静态修饰符)指定变量被所有对象共享,即所有实例都可以使用该变量。变量属于这个类。 被static修饰的成员变量,叫做静态变量。
特点:被所有实例化对象共享
调用方式:
类名. 调用(推荐)
对象名调用
静态变量是随着类的加载而加载的,优先于对象出现 堆内存中开辟一个静态区,存储,所有对象共享
被sataic修饰的成员方法,叫静态方法
class Student{
String name;
String gender;
static String classes = "1班";
public Student(String name, String gender) {
this.name = name;
this.gender = gender;
}
public void print(){
System.out.println("姓名:" + this.name+"性别:" + this.gender + "班级:" + this.classes);
}
}
public class Test {
public static void main(String[] args) {
Student student1 = new Student("张三","男");
Student student2 = new Student("李四","男");
Student student3 = new Student("王五","女");
student1.print();
student2.print();
student3.print();
}
}
1:非静态成员变量:需要创建对象来访问
2:静态成员变量:使用类名直接调用,也可以通过对象访问
使用场景: 当对象中出现共享数据时
transient(过度修饰符)指定该变量是系统保留,暂无特别作用的临时性变量。
volatile(易失修饰符)指定该变量可以同时被几个线程控制和修改。
方法修饰符:
public(公共控制符)
private(私有控制符)指定此方法只能有自己类等方法访问,其他的类不能访问(包括子类)
protected(保护访问控制符)指定该方法可以被它的类和子类进行访问。
final,指定该方法不能被重载。
static,指定不需要实例化就可以激活的一个方法。可以直接用 类名.方法名() 的方式调用
可以使用类名直接调用
1:静态函数中不能访问非静态成员变量,只能访问静态变量。
2:静态方法不可以定义this,super关键字.
3:因为静态优先于对象存在.静态方法中更不可以出现this super
4:非静态函数:非静态函数中可以访问静态成员变量
使用场景:当函数中没有访问到非静态数据时,一般多见于工具类中,因为方便使用 类名.方法名()来使用工具。
synchronize,同步修饰符,在多个线程中,该修饰符用于在运行前,对他所属的方法加锁,以防止其他线程的访问,运行结束后解锁。
native,本地修饰符。指定此方法的方法体是用其他语言在程序外部编写的。
final
- 1、final修饰方法:最终方法,不能被重写
- 2、final修饰类:最终类,不能被继承
- 3、final修饰变量:是常量,不能被修改
基本数据类型:变量的值不能修改
引用数据类型,地址值不能修改,内部的属性值可以修改
常量命名规范:单个单词全部大写,多个单词,全部大写,单词之间用下划线连接
方法
方法(method)完成某一个特定功能的代码块。
修饰符 返回值类型 方法名(参数列表){
//代码省略...
return 结果;
}
- 修饰符: public static 目前固定写法
- 返回值类型: 表示方法运行的结果的数据类型,方法执行后将结果返回到调用者
- 参数列表: 方法在运算过程中的未知数据,调用者调用方法时传递
- return: 将方法执行后的结果带给调用者,方法执行到 return ,整体方法运行结束
- 小贴士:return 结束; 这里的结束在开发中,我们正确的叫法成为方法的返回值
tips:
- 定义位置:类中方法外,不能嵌套定义
- 方法必须先定义,再使用
- void表示无返回值,可以省略return,也可以单独的书写return
- 不能在return后面写代码,return意味着方法结束,所有后面的代码记永远都不会执行,属于无效代码
方法重载overload
也就是方法重写
1、重写的方法名称,形参列表必须和父类中的一致
2、子类重写父类方法时,访问权限子类必须大于父类(空着不写<protected<public)
3、子类重写父类方法时,返回值类型必须小于等于父类(不容易理解)
4、建议:重写的方法尽量和父类保持一致
5、只有能被添加到虚方法表中的方法才能重写 (非private 非static 非final)
-
在同一个类中,具有相同的方法名, 参数列表不同(参数的个数、类型、顺序不同),与返回值无关。
-
参数列表:个数不同,数据类型不同,顺序不同。
-
重载方法调用:JVM通过方法的参数列表,调用不同的方法。
- 重载仅对应方法的定义,与方法的调用无关,调用方式参照标准格式。
- 重载仅针对同一个类中方法的名称与参数进行识别,与返回值无关,换句话说不能通过返回值来判定两个方法是否相互构成重载。
引号用于表示不可变字符串,而单引号表示字符。
字符串的操作方法:blog.csdn.net/weixin_6976…
字符串的比较
- equals()方法
- ==
- equalsIgnoreCase()方法
- compareTo()方法
equals() 方法是最常用的比较字符串内容的方法。它比较两个字符串的内容是否相等,返回一个布尔值。
String str1 = "abcdef";
String str2 = "Abcdef";
boolean ret = str1.equals(str2);
System.out.println(ret);
使用==进行比较时
对于基本数据类型:比较的是数据值
对于引用数据类型:比较的是地址值
String str1 = "abcdef";
String str2 = "abcdef";
String str3 = new String("abcdef");
String str4 = new String("abcdef");
System.out.println(str1 == str2); //true
System.out.println(str1 == str3);//false
System.out.println(str3 == str4); //false
//JVM为了避免字符串的重复创建,节省内存,
//提升性能,维护了一块特殊的内存空间,即字符串池(String Pool)
//当创建一个字符串时,JVM首先会在字符串池中查找是否存在该字符串,
//若不存在,则在字符串池中创建该字符串;若字符串中已存在该字符串,则直接将池中字符串的地址返回
//当通过new的方式创建对象时,创建出来的对象都是存放在堆栈里面的,每new一次则是在堆栈中创建一个新的对象。
equalsIgnoreCase() 方法的作用与语法与equals()方法相同,唯一的不同点在于equalsIgnoreCase()方法在比较时不区分大小写
compareTo()方法
compareToIgnoreCase(String str) 方法:与compareTo方式相同,但是忽略大小写比较
//比较两个字符串,逐一比较每个字符,当相比较的两个字符不同时,返回不同字符的ASCII码的差值
String str1 = "abcdef";
String str2 = "abcDef";
int ret = str1.compareTo(str2);
System.out.println(ret); //32
//若两个字符串长度不同,但参与比较的字符相同,则返回两个字符串长度的差值
String str1 = "abcdef";
String str2 = "abc";
int ret = str1.compareTo(str2);
System.out.println(ret); //3
//**返回正数表示str1 > str2 ,返回负数表示str1 < str2,返回0表示str1 与str2相等**
Scanner
Scanner类是Java标准库中的一个类,位于java.util包中。它用于解析基本类型(如int、double等)和字符串,可以从多种输入源读取数据,包括控制台、文件、字符串等。
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
// 创建Scanner对象,从控制台读取输入
//`System.in` 是 `System` 类的一个静态成员变量,它是一个 `InputStream` 类型的对象。
//它代表了标准输入流,默认情况下与键盘输入相关联。
//因此,当你看到 `Scanner scanner = new Scanner(System.in)` 这行代码时,
//它实际上是在创建一个 `Scanner` 对象,该对象可以用来读取从键盘输入的数据。
Scanner scanner = new Scanner(System.in);
System.out.print("Enter your name: ");
String name = scanner.nextLine(); // 读取一行字符串
System.out.print("Enter your age: ");
int age = scanner.nextInt(); // 读取一个整数
System.out.println("Hello, " + name + "! You are " + age + " years old.");
scanner.close(); // 关闭Scanner对象
}
}
-
nextLine():读取一行字符串,包括空格。 -
next():读取下一个单词(以空格或换行符分隔)。 -
nextInt():读取一个整数。 -
nextDouble():读取一个双精度浮点数。 -
nextBoolean():读取一个布尔值。 -
nextByte():读取一个字节。 -
nextShort():读取一个短整数。 -
nextLong():读取一个长整数。 -
nextFloat():读取一个单精度浮点数。
当嵌套循环嵌套或者 循环嵌套判断语句时,退出 外层循环
public class StudentSystem {
public static void main(String[] args) {
loop: while (true) {
System.out.println("------------------欢迎来到学生管理系统---------------------");
System.out.println("1、添加学生");
System.out.println("2、删除学生");
Scanner sc = new Scanner(System.in);
String chooseVal = sc.next();
switch (chooseVal) {
case "1":
System.out.println("添加学生");
break;
case "2":
System.out.println("删除学生");
break;
case "3":
System.out.println("修改学生");
break;
case "4":
System.out.println("查询学生");
break;
case "5":
System.out.println("退出");
//break loop; //给循环起名字,终止它
//System.exit(0); //退出虚拟机运行()
default:
System.out.println("没有这个选项");
break;
}
}
}
}
静态方法
public class Animal {
//- **定义**:实例方法是属于类的实例(对象)的方法。它们必须通过类的实例来调用。
//- **访问方式**:要调用实例方法,你需要先创建类的实例(对象),然后通过这个实例来调用方法。
//- **上下文**:实例方法可以访问类的所有成员,包括实例变量和其他实例方法。
public void eat() {}
//定义:静态方法是属于类本身的方法,而不是类的实例。它们可以通过类名直接调用,无需创建类的实例。
//访问方式:静态方法可以直接通过类名来调用,也可以通过类的实例调用,
//但通常推荐使用类名调用以提高代码的可读性。
//**上下文:静态方法只能访问类的静态成员(静态变量和其他静态方法),不能直接访问实例成员。
public static void eat1(){}
}
常用API
ArrayList
ArrayList<String> list = new ArrayList<>();
//添加
Boolean flg = list.add("A");
list.add("B");
//删除
Boolean aa = list.remove("A");
String li = list.remove(0);
//修改
list.set(0, "C");
//查询
String s = list.get(0);
//遍历
for (int i = 0; i < list.size(); i++) {
System.out.println(list.get(i));
}
for (String str : list) {
System.out.println(str);
}
Math
System
Runtime
集合
Java 集合,也叫作容器,主要是由两大接口派生而来:一个是 Collection接口,主要用于存放单一元素;另一个是 Map 接口,主要用于存放 键值对
- List:存储的元素是有序可重复的。
- Set:存储的元素是无序不可重复的。
- Queue: 按特定的排队规则来确定先后顺序,可重复
- Map: 使用键值对(key-value)存储,key 是无序的、不可重复的,value 是无序的、可重复的,每个键最多映射到一个值。
声明数组
//声明一个整型数组
int[] intArray;
4// 声明一个字符串数组
5String[] stringArray;
7// 初始化数组
8int[] intArray = new int[10]; // 创建一个长度为10的整型数组
9String[] stringArray = new String[]{"a", "b", "c"}; // 创建并初始化一个字符串数组
声明集合
// 初始化List集合
List<String> userIds = new ArrayList<>();
int[] arr = {1,2,3,4}
List<String> stringList = new ArrayList<>(); // 创建一个ArrayList实例
// 添加元素到集合
stringList.add("a");
stringList.add("b");
stringList.add("c");
// 声明并初始化
List<String> stringList = new ArrayList<>(Arrays.asList("a", "b", "c"));
// 声明并初始化一个Set集合
Set<String> stringSet = new HashSet<>();
// 创建一个 LinkedHashSet
LinkedHashSet<String> linkedHashSet = new LinkedHashSet<>();
// 添加元素
linkedHashSet.add("A");
linkedHashSet.add("B");
linkedHashSet.add("C");
- **有序性**:LinkedHashSet 会保持元素的插入顺序,即元素被添加到集合中的顺序就是它们在集合中的顺序。
- **唯一性**:与 HashSet 一样,LinkedHashSet 保证元素的唯一性,不允许重复元素。
- **性能**:由于 LinkedHashSet 使用哈希表存储元素,因此它提供了快速的查找性能。同时,它还使用链表来维护元素的插入顺序。
// 声明并初始化一个Map集合
Map<String, Integer> map = new HashMap<>();
// 创建一个 TreeMap
TreeMap<String, Integer> treeMap = new TreeMap<>();
// 插入键值对
treeMap.put("apple", 10);
treeMap.put("banana", 20);
treeMap.put("orange", 30);
// 声明并初始化LinkedList
LinkedList<String> linkedList = new LinkedList<>();
Stream
public class Demo {
public static void main(String[] args) {
ArrayList<String> names = new ArrayList<>();
Collections.addAll(names, "张三丰", "张无忌", "周芷若", "赵敏", "张三", "韦一笑");
// 方案一:传统遍历
List<String> list = new ArrayList<>();
for (String name : names) {
if (name.startsWith("张") && name.length() == 3) {
list.add(name);
}
}
System.out.println(list); // [张三丰, 张无忌]
// 方案二:Stream
List<String> list2 = names.stream()
.filter(name -> name.startsWith("张") && name.length() == 3)
.collect(Collectors.toList());
System.out.println(list2); // [张三丰, 张无忌]
}
}
Stream的方法
filter:根据给定的条件过滤出符合条件的元素。 map:将每个元素通过给定的函数映射成另一个元素(对每一项数据进行加工处理)。 peek:对流中的每个元素执行操作并返回一个新的流,主要用于调试。 sorted:对Stream中的元素进行排序。
public static void sorted() {
List<Integer> numbers = Arrays.asList(8, 3, 6, 7, 5);
List<Integer> sortedNumbers = numbers.stream()
.sorted((a, b) -> a - b)
.collect(Collectors.toList());
System.out.println(sortedNumbers); // [3, 5, 6, 7, 8]
}
distinct:去除Stream中的重复元素。
public static void distinct() {
List<String> daxias = Arrays.asList("张无忌", "赵敏", "张无忌", "周芷若", "赵敏");
List<String> distinctDaxias = daxias.stream()
.distinct()
.collect(Collectors.toList()); // [张无忌, 赵敏, 周芷若]
System.out.println(distinctDaxias);
}
reduce:对Stream中的元素进行归约操作,可以实现求和、求最大值、求最小值等操作。
public static void reduce() {
List<Integer> numbers = Arrays.asList(8, 3, 6, 7, 5);
// 求和
Integer sum1 = numbers.stream().reduce((a, b) -> a + b).get();
Integer sum2 = numbers.stream().reduce(Integer::sum).get();
System.out.println("sum1: " + sum1 + ",sum2:" + sum2); // sum1: 29,sum2:29
// 最大值
Integer max1 = numbers.stream().reduce((a, b) -> a > b ? a : b).get();
Integer max2 = numbers.stream().reduce(Integer::max).get();
System.out.println("max1:" + max1 + ",max2:" + max2); // max1:8,max2:8
// 最小值
Integer min1 = numbers.stream().reduce((a, b) -> a < b ? a : b).get();
Integer min2 = numbers.stream().reduce(Integer::min).get();
System.out.println("min1:" + min1 + ",min2:" + min2); // min1:3,min2:3
}
limit:限制Stream中元素的数量。
public static void limit() {
List<Integer> numbers = Arrays.asList(8, 3, 6, 7, 5);
List<Integer> limitedNumbers = numbers.stream()
.limit(3)
.collect(Collectors.toList());
System.out.println(limitedNumbers); // [8, 3, 6]
}
skip:跳过Stream中的前几个元素。
public static void skip() {
List<Integer> numbers = Arrays.asList(8, 3, 6, 7, 5);
List<Integer> limitedNumbers = numbers.stream()
.skip(2)
.collect(Collectors.toList());
System.out.println(limitedNumbers); // [6, 7, 5]
}
lambda表达式
//也就类似于js中的箭头函数
stream.filter(s -> s.startsWith("张")).forEach(n -> System.out.println(n));
方法引用
静态: 类名::方法名 构造方法: 类名::方法名
引用成员方法: 其他类: 其他类对象::方法名 本类:this::方法名 父类:super::方法名
ArrayList<String> names2 = new ArrayList<>();
Collections.addAll(names2,"1","2","3","4","5","6");
names2.stream().map(Integer::parseInt).forEach(System.out::println);
File
1、file对象表示路径,可以是文件,可以是文件夹 这个路径可以是存在的,可以是不存在的
2、绝对路径和相对路径 绝对路径是带盘符的,相对路径是不带盘符的,默认到当前项目下去找
3、File三种构造
public File (String pathName)
public File(String parent , String child)
public File(File parent ,String child)
String str = "c:\users\Desktop\a.text";
File file = new File(str);
System.out.println(file);v
IO 流
-
流的方向: 输入流,输出流
-
操作文件类型:
字节流:所有类型文件
字符流:纯文本文件 .txt .md .xml .lrc
写出数据
FileOutputStream fos = new FileOutputStream("C:\Users\zhangjinzhong\Desktop\aa\aa.txt");
fos.write(97);
fos.close();