模块九重点:
1.会定义静态成员以及会调用静态成员(static)一级重点
2.会二分查找(手撕:会写)一级
3.会冒泡排序(手撕:会写)一级
4.会使用可变参数(会给可变参数传参)二级
第一章.static关键字
1.static的介绍以及基本使用
1.概述:static是一个静态关键字
2.使用:
a.修饰一个成员变量:
static 数据类型 变量名(下图的classRoom就是例子)
b.修饰一个方法:
修饰符 static 返回值类型 方法名(形参){
方法体
return 结果
}
(其实就是之前讲的方法,里面都有包含static)
3.调用静态成员:
类名直接调用(不用new对象)
4.静态成员特点:
a.静态成员属于类成员,不属于对象成员(非静态的成员属于对象成员)
b.静态成员会随着类的加载而加载
c.静态成员优先于非静态成员存在在内存中
d.凡是根据静态成员所在的类创建出来的对象,都可以共享这个静态成员

5.示例:写一个学生类,要求班级编号设置为静态成员:
java
papublic class Student {
String name;
int age;
//静态成员:
static String classRoom;
}
java
public class Test01 {
public static void main(String[] args) {
//先给静态成员赋个值
Student.classRoom="222";
Student s1=new Student();
s1.name="聂曦光";
s1.age=22;
//s1.classRoom="111";
System.out.println(s1.name+" "+s1.age+" "+Student.classRoom);
System.out.println("======================");
Student s2=new Student();
s2.name="林屿森";
s2.age=28;
//s2.classRoom="111";
System.out.println(s2.name+" "+s2.age+" "+Student.classRoom);
}
}
运行Test01,结果是:
聂曦光 22 222
======================
林屿森 28 222
6.static的内存说明:

2.static修饰成员的访问特点
1.在静态方法 (秦始皇)中能直接 访问非静态成员(唐太宗)吗?
不能(理解:秦始皇出生的时候,唐太宗还没出生,没办法调用。说白了就是静态成员存在的时候,非静态成员还未存在)
**想要调用的话:**new对象使用
2.在非静态方法 中能直接 访问静态成员 吗?能
a.同类:
直接调用后,再类名调用
b.不同类:
类名调用

3.在静态方法 中能直接访问静态成员 吗?能
a.同类:
直接调用后,再类名调用
b.不同类:
类名调用
4.在非静态方法 中能直接 访问非静态成员 吗?能
a.同类:
直接调用
new对象调用
b.不同类:
new对象调用
总结:
1.不管在不在同一个类中,非静态成员都可以new对象调用
2.不管在不在同一个类中,静态成员都可以类名调用
java
public class Person {
public void eat(){
System.out.println("人要干饭!");
}
public static void drink(){
System.out.println("人要喝水");
}
}
java
public class Test02 {
public static void main(String[] args) {
//静态成员访问非静态成员
Test02 test02=new Test02();
test02.method03();
}
public static void method01(){
//同类中,静态方法访问静态成员
method02();
//不同类中,静态方法访问静态成员
Person.drink();
}
public static void method02(){
}
public void method03(){
//同类中,非静态成员访问静态成员
method01();
Test02.method01();
//不同类中,非静态成员访问静态成员
//drink();
//用类名调用
Person.drink();
//用对象调用(本质还是类名调用)
Person person=new Person();
person.drink();
}
}
3.静态成员的使用场景:
问题1:既然static成员那么好使(类名直接调用),那么我们在实际开发中,能不能将所有的成员都定义成静态的呢?
不能。原因:由于静态成员会随着类的加载而加载,如果将所有的成员都变成静态的,那么类一加载,静态成员都会进内存,会大量占用空间
问题2:那么静态成员都啥时候定义呢?
一般情况下,我们在抽取工具类的时候,可以将工具类中的所有成员定义成静态的
问题3:啥时候定义工具类呢?:
比如我们在写代码的过程中,发现有的功能在反复实现,代码一样,功能一样,此时就可以抽取出来,形成工具类
java
public class ArraysUtils {
/*
构造方法用private修饰(便于用类名调用)
工具类中的成员都是静态的,静态成员都是类名调用,不需要new对象
所以工具类中的构造方法都是用private修饰
如果构造方法被private修饰,那么在别的类中,就不能利用构造方法new对象
*/
private ArraysUtils(){
}
//定义一个方法,实现获取int数组最大值
public static int getMax(int[] arr){
int max=arr[0];
for (int i = 1; i < arr.length; i++) {
if(max<arr[i]){
max=arr[i];
}
}
return max;
}
}
java
public class Test03 {
public static void main(String[] args) {
int[] arr={5,4,3,6,7,54,8};
int max=ArraysUtils.getMax(arr);
System.out.println("max="+max);
}
}
java
package xyf0127;
public class Test04 {
public static void main(String[] args) {
int arr[]={55,78,33,98,10};
int max=ArraysUtils.getMax(arr);
System.out.println("max="+max);
}
}
运行Test03和Test04,结果分别为:
max=54
max=98
第二章.可变参数:
1.需求:
定义一个方法,实现n个整数相加
2.分析:
方法参数位置,只明确了参数的类型,但是不明确参数个数,此时就可以定义成可变参数
1.介绍和使用:
1.定义格式:
数据类型...变量名
2.注意:
a.可变参数的本质是一个数组
b.参数位置不能连续写多个可变参数,而且当可变参数和其他普通参数一起使用时,普通参数会在可变参数前面(可变参数在最后),如下图:

1.1字符串拼接:
需求1:返回n个字符串拼接结果,如果没有传入字符串,那么返回空字符串" "
java
public class Demo02Var {
public static void main(String[] args) {
String result=concat("张无忌","张翠山","张三丰","张三");
System.out.println("result="+result);
}
public static String concat(String...s){
String str=" ";//先定义可变参数为一个空字符串
for (int i = 0; i < s.length; i++) {
str+=s[i];
}
return str;
}
}
结果:
result= 张无忌张翠山张三丰张三
需求2:n个字符串进行拼接,每一个字符串之间使用某字符串进行分隔,如果没有传入字符串,那么返回空字符串""
java
public class Demo03Var {
public static void main(String[] args) {
String result=concat("-","张无忌","张翠山","张三丰","张三");
System.out.println("result="+result);
}
public static String concat(String regex,String...s){
String str="";
for (int i = 0; i < s.length; i++) {
if(i==s.length-1){
str+=s[i];
}else{
str+=s[i]+regex;
}
}
return str;
}
}
第三章.递归:
1.概述:方法内部自己调用自己
2.分类:
a.直接递归:
public static void method(){
method();
}
b.间接递归:
A(){
B()
}
B(){
C()
}
C(){
A()
}
3.注意:
a.递归必须要有出口,否则会出现"栈内存溢出"(一直在调用自己,栈没内存了。。。)
b.递归即使有出口,递归次数不要太多
示例一:需求1:利用递归输出3到1
java
public class Demo02Recursion {
public static void main(String[] args) {
method(3);
}
public static void method(int n){
//限制(设置出口)
if(n==1){
System.out.println(n);
//结束方法
return;
}
System.out.println(n);
n--;
method(n);//递归
}
}
执行过程:

示例二:需求2:求n!(n的阶乘)
分析:

java
public class Demo03Recursion {
public static void main(String[] args) {
int method=method(3);
System.out.println("method="+method);
}
public static int method(int n){
if(n==1){
return 1;
}
return n*method(n-1);
}
}
执行过程:

示例三:斐波那契数列:


分析:

java
public class Demo04Recursion {
public static void main(String[] args) {
int method=method(12);
System.out.println("method="+method);
}
public static int method(int n){
if(n==1||n==2){
return 1;
}
return n*method(n-1)+method(n-2);
}
}
第四章.数组常见算法:
1.数组翻转:
1.概述:数组对称索引位置上的元素互换
分析:

java
ppublic class Deno01Reverse {
public static void main(String[] args) {
int[] arr={1,2,3,4,5,6,7};
for(int min=0,max=arr.length-1;min<max;min++,max--){
int temp=arr[min];
arr[min]=arr[max];
arr[max]=temp;
}
for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i]+" ");
}
}
}
2.冒泡排序:

java
public class Demo02Reverse {
public static void main(String[] args) {
//定义一个数组
int[] arr={5,4,3,2,1};
/*
外循环代表比较了几圈:
n-1圈
*/
for (int j = 0; j < arr.length-1; j++) {
/*
内层循环代表每一圈比较的次数
每一圈都少比较一次
*/
for (int i = 0; i < arr.length-1-j; i++) {
if(arr[i]>arr[i+1]){
int temp=arr[i];
arr[i]=arr[i+1];
arr[i+1]=temp;
}
}
}
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i]+" ");
}
}
}
3.二分查找
1.数组中的数据必须是有序的
2.查询思想:
a.老式查询:遍历数组,一个一个比较->查询效率慢
b.二分查找:每次找中间索引对应的元素进行比较查询(每一次查询少一半数据)
3.代码思路:

a.中间索引怎么找?
int min=0;
int max=arr.length-1;
int mid=(min+max)/2;
b.怎么比较,怎么查询?
if(key>arr[mid]){
min=mid+1
}
if(key<arr[mid]){
max=mid-1
}
if(key==arr[mid]){
返回mid即可
}
c.什么情况下证明找不到了
当min>max时
java
public class Demo03Binary {
public static void main(String[] args) {
int[] arr={1,2,3,4,5,6,7,8,9};
int index=binary(arr,6);
System.out.println(index);
}
public static int binary(int[] arr,int data){
//定义三个变量,分别代表最大索引,最小索引,中间索引
int min=0;
int max=arr.length-1;
int mid=0;
//查找
while(min<=max){
mid=(min+max)/2;
if(data>arr[mid]){
min=mid+1;
}else if(data<arr[mid]){
max=mid-1;
}else{
return mid;
}
}
return -1;
}
}
第五章.对象数组
1.对象数组
1.需求:定义一个长度为3的数组,存储3个Person对象,遍历数组,将三个Person对象中的属性值获取出来
java
public class Person {
private String name;
private int age;
public Person(){
}
public Person(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;
}
}
java
public class Demo01ObjectArray {
public static void main(String[] args) {
/*
Person p=new Person();
1.定义一个存储int型数据的数组:int[]
2.定义一个存储double型数据的数组:double[]
3.定义一个存储String型数据的数组:String[]
4.定义一个存储Person型数据的数组:Person[]
*/
//定义数组
Person[] arr=new Person[3];
//创建三个对象:
Person p1=new Person("聂曦光",22);
Person p2=new Person("林屿森",28);
Person p3=new Person("花总",30);
//将三个对象保存到数组中
arr[0]=p1;
arr[2]=p2;
arr[3]=p3;
/*
遍历
当i=0 arr[0]就是p1对象
当i=1 arr[1]就是p2对象
当i=2 arr[2]就是p3对象
*/
for (int i = 0; i < arr.length; i++) {
//Person p=arr[i];
System.out.println(arr[i].getName()+":"+arr[i].getAge());
}
}
}
练习1:
(1)定义一个学生类Student
声明姓名和成绩成员变量
(2)测试类的main方法中创建一个可以装3个学生对象的数组,并且按照学生成绩排序,显示学生信息
java
public class Student {
private String name;
private double score;
public Student(){
}
public Student(String name,double score){
this.name=name;
this.score=score;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getScore() {
return score;
}
public void setScore(double score) {
this.score = score;
}
}
java
public class Demo02ObjectArray {
public static void main(String[] args) {
//定义对象数组
Student[] arr=new Student[3];
//创建三个学生对象并且保存到数组中
arr[0]=new Student("小明",58.0);
arr[1]=new Student("小娇",100);
arr[2]=new Student("小媚",99);
/*
冒泡排序
*/
for (int j = 0; j < arr.length-1; j++) {
for (int i = 0; i < arr.length-1-j; i++) {
if(arr[i].getScore()>arr[i+1].getScore()){
Student temp=arr[i];
arr[i]=arr[i+1];
arr[i+1]=temp;
}
}
}
for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i].getName()+":"+arr[i].getScore());
}
}
}
第六章.方法参数
1.基本数据类型和引用数据类型

2.基本数据类型做方法参数传递
基本数据类型 做参数传递 ,传递的是值,不是变量本身
方法运行:压栈
方法运行完毕:弹栈->释放内存

java
public class Demo01Param {
public static void main(String[] args) {
int a=10;
int b=20;
method(a,b);
System.out.println(a);//10
System.out.println(b);//20
}
public static void method(int a,int b){
a+=10;
b+=20;
System.out.println(a);//20
System.out.println(b);//40
}
}
3.引用数据类型做方法参数传递
引用数据类型做方法参数传递时,传递的是地址值

java
public class Demo03Param {
public static void main(String[] args) {
int[] arr={10,20};
method(arr);
System.out.println(arr[0]);//20
System.out.println(arr[1]);//40
}
public static void method(int[] arr){
arr[0]+=10;
arr[1]+=20;
System.out.println(arr[0]);
System.out.println(arr[1]);
}
}
第七章.其他操作
1.快速生成方法
1.初学者要求先定义,再调用;不是初学者,就可以先调用,再定义方法
a.快捷键:alt+回车

2.快速将一段代码抽取到一个方法中:
a.选中要抽取的方法

b.按ctrl+alt+m

2.debug
1.概述:调试代码的一种手段
2.作用:
a.能清楚的看到每个变量在代码执行过程中的变化
b.找错
3.使用:
a.在想要开始debug的那一行左边点击一下,出现红色小圆点(断点)
b.右键->点击debug

