第一章 Static关键字
1.static的介绍以及基本使用
1.概述:static是一个静态关键字
2.使用:
a.修饰一个成员变量:
static 数据类型 变量名
b.修饰一个方法:
修饰符 static 返回值类型 方法名(形参){
方法体
return 结果
}
3.调用静态成员:
类名直接调用(不用new对象)
4.静态成员特点:
静态成员属于类成员,不属于对象成员(非静态成员属于对象成员)
静态成员会随着类的加载而加载
静态成员优先于非静态成员存在在内存中
凡是根据静态成员所在的类创建出来的对象都可以共享这个静态成员
public class Student {
String name;
int age;
static String ClassRoom;
}
public class Test01 {
public static void main(String[] args) {
//先给静态成员赋个值
Student.ClassRoom = "后陡门58号";
Student s1 = new Student();
s1.name = "张钥沅";
s1.age = 26;
// s1.ClassRoom = "后陡门58号";
System.out.println(s1.name+","+s1.age+","+Student.ClassRoom);
System.out.println("========================");
Student s2 =new Student();
s2.name = "路卓豪";
s2.age = 29;
// s2.ClassRoom = "后陡门58号";
System.out.println(s2.name+","+s2.age+","+Student.ClassRoom);
}
}
2.static修饰成员的访问特点
1.在静态方法中能直接访问非静态成员吗?不能
想要调用的话需要先new对象调用
2.在非静态方法中能直接访问静态成员吗?能
同类中可以直接调用,也可以类名调用
不同类中类名调用
3.在静态方法中能直接访问静态成员吗?能
同类中可以直接调用,也可以类名调用
不同类中类名调用
4.在非静态方法中能直接访问非静态成员吗?能
同类直接调用,也可以new对象调用
不同类new对象调用
总结:
1.不管在不在同一个类中,非静态成员都可以new对象调用
2.不管在不在同一个类中,静态成员都可以类名调用
问题1:既然static成员那么好使(类名直接调用),那么我们在实际开发中,能不能将所有的成员都定义成静态的?不能
由于静态成员会随着类的加载而加载,如果将所有的成员都定义成静态的,那么类一加载静态成员都会进内存,会大量占用内存空间,所以说不能把所有的成员定义成静态成员
问题2:静态成员都啥时候定义?
一般情况下,我们在抽取工具类的时候,可以将工具类中所有的成员都定义成静态的
问题3:啥时候定义工具类?
我们在写代码的时候发现有的功能在反复实现,代码一样功能一样,此时就可以抽取出来,形成工具类
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;
}
}
public class Test01 {
public static void main(String[] args) {
int[] arr = {5,34,7,3,45,12};
// int max = arr[0];
// for (int i=1;i<arr.length;i++){
// if (max<arr[i]){
// max = arr[i];
// }
// }
// System.out.println("max = " + max);
int max = ArraysUtils.getMax(arr);
System.out.println("max = " + max);
}
}
public class Test02 {
public static void main(String[] args) {
int[] arr = {2,354,56,78,54,3,65,6};
// int max =arr[0];
// for (int i=1;i<arr.length;i++){
// if (max<arr[i]){
// max = arr[i];
// }
// }
// System.out.println("max = " + max);
int max = ArraysUtils.getMax(arr);
System.out.println(max);
}
}
第二章 可变参数
需求:定义一个方法,实现n个整数相加
分析:
方法参数位置,只明确参数类型,但是不明确参数个数,此时就可以定义成可变参数
1.可变参数的使用和注意事项
1.定义格式:
数据类型...变量名
2.注意:
可变参数的本质是一个数组
参数位置不能连续写多个可变参数,而且当可变参数和其他普通参数一起使用时,可变参数需要放到列表最后
public class Demo01Var {
public static void main(String[] args) {
sum(1,2,3,4,5);
sum1(1,1,2,3,4,5);
}
public static void sum(int...arr){
int sum = 0;
for (int i = 0; i < arr.length; i++) {
sum+=arr[i];
}
System.out.println(sum);
}
public static void sum1(int i,int...arr){
}
}
2.可变参数的练习
需求1:返回n个字符串拼接结果,如果没有传入字符,那么返回经字符串“”
public class Demo02Var {
public static void main(String[] args) {
/*
返回n个字符串拼接结果,如果没有传入字符,那么返回经字符串“”
*/
String str = concat("蒋敦豪","鹭卓","李耕耘","李昊","赵一博","卓沅","赵小童");
System.out.println("str = " + str);
}
public static String concat(String...s){
String str = "";
for (int i= 0;i<s.length;i++){
str+=s[i];
}
return str;
}
}
需求2:n个字符串进行拼接,每一个字符串之间使用某字符进行分隔,如果没有字符串,那么返回空字符串“”
public class Demo03Var {
public static void main(String[] args){
/*
n个字符串进行拼接,每一个字符串之间使用某字符进行分隔,如果没有字符串,那么返回空字符串“”
*/
String str = concat("-","蒋敦豪","鹭卓","李耕耘");
System.out.println("str = " + str);
}
public static String concat(String s1,String...s2){
String str = "";
for (int i = 0; i < s2.length; i++) {
if (i!=s2.length-1){
// str = str+s2[i]+s1;
str+=s2[i]+s1;
}else {
str+=s2[i];
}
}
return str;
}
}
第三章 递归
1.概述:方法内部自己调用自己
2.分类:
a.直接递归:
public static meyhod(){
method();
}
b.间接递归:
A(){
B();
}
B(){
C();
}
C(){
A();
}
3.注意:
递归必须要有出口,否则就会出现栈内存溢出
递归即使有出口,递归次数也不要太多
public class Demo01Recursion {
public static void main(String[] args) {
method();
}
public static void method(){
method();
}
}
示例1:利用递归输出3到1
法1:
public class Demo02Recursion {
public static void main(String[] args) {
method(3);
}
public static void method(int i){
System.out.print(i+" ");
if (i-1>0){
method(i-1);
}
}
}
法2:
public class Demo02Recursion {
public static void main(String[] args) {
method(3);
}
// public static void method(int i){
// System.out.print(i+" ");
// if (i-1>0){
// method(i-1);
// }
// }
public static void method(int i){
if (i==1){
System.out.println(i);
//结束方法
return;
}
System.out.print(i+" ");
method(i-1);
}
}
示例2:求n!(n的阶乘)
需求:定义一个方法,完成3的阶乘 3*2*1
分析:假如定义一个方法,代表n的阶乘 ->method(n) n接收几,就代表几的阶乘
public class Demo03Recursion {
public static void main(String[] args) {
int method = method(3);
System.out.println(method);
}
public static int method(int i){
if (i==1){
return 1;
}
return i*method(i-1);
}
}
示例3:求斐波那契数列
规律:一个数等于前两个数之和,比如 1,1,2,3,5,8,13,21,34,55......
public class Demo04Recursion {
public static void main(String[] args) {
int result = method(12);
System.out.println("result = " + result);
}
public static int method(int month){
if(month==1||month==2){
return 1;
} else {
return method(month-1)+method(month-2);
}
}
}
第四章 数组常见算法
1.数组翻转
1.概述:数组对称索引位置上的元素互换
法1:
public class Demo01Arrays {
public static void main(String[] args) {
int[] arr1 = {1,2,3,4,5,6,7};
int[] arr2 = Reverse(arr1);
for (int i=0;i<arr1.length;i++){
System.out.print(arr1[i]+" ");
}
System.out.println();
for (int i=0;i<arr2.length;i++){
System.out.print(arr2[i]+" ");
}
}
public static int[] Reverse(int[] arr){
if (arr.length!=0){
int[] newarr = new int[arr.length];
int min = 0;
int max = newarr.length-1;
int mid = (min+max)/2;
for (int i=0;i<=mid;i++){
newarr[min] = arr[max];
newarr[max] = arr[min];
min++;
max--;
}
return newarr;
}else {
return arr;
}
}
}
法2:
public class Demo02Arrays {
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.print( arr[i]+" ");
}
}
}
2.冒泡排序
数组的排序,是将数组中的元素按照大小进行排序,默认都是以升序形式进行排序,数组排序的方法很多,我们讲解的是数组的冒泡排序
排序,都要进行数组元素的大小比较,在进行位置的交换,冒泡排序是采用数组中相邻元素进行比较换位
法1:
public class Demo03Arrays {
public static void main(String[] args) {
int[] arr = {2,35,6,8,97,3,57};
BobbleSort(arr);
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i]+" ");
}
}
public static int[] BobbleSort(int[] arr) {
for (int i=1;i<arr.length;i++){
for (int max = arr.length - 1; max > 0; max--) {
if (arr[max] < arr[max - 1]) {
int temp = arr[max];
arr[max] = arr[max - 1];
arr[max - 1] = temp;
}
}
}
return arr;
}
}
法2:
public class Demo04Arrays {
public static void main(String[] args) {
int[] arr = {2,35,6,8,97,3,57};
BobbleSort(arr);
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i]+" ");
}
}
public static int[] BobbleSort(int[] arr) {
for (int i = 0; i < arr.length-1; i++) {
for (int j = 0; j < arr.length-1-i; j++) {
if (arr[j]>arr[j+1]){
int temp = arr[j];
arr[j] =arr[j+1];
arr[j+1] = temp;
}
}
}
return arr;
}
}
控制台输入一组数,进行冒泡排序,并且打印输出
import java.util.Scanner;
public class Demo05Arrays {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("请输入想要排序的数字个数:");
int n = sc.nextInt();
int[] arr = new int[n];
System.out.println("请输入想要排序的"+n+"个数:");
for (int i = 0; i < n; i++) {
arr[i]=sc.nextInt();
}
boolean swapped = false;
for (int j = 0; j < n-1; j++) {
for (int i = 0; i < n-1-j; i++) {
if (arr[i]>arr[i+1]){
int temp = arr[i];
arr[i] =arr[i+1];
arr[i+1] =temp;
swapped = true;
}
}
if (!swapped){
System.out.println("不需要排序");
break;
}
}
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i]+" ");
}
}
}
3.二分查找
1.前提:数组中的数据必须是有序的
2.查询思想:
a.老式查询:遍历数组,一个一个比较,查询效率慢
b.二分查找:每次找中间索引对应的元素进行比较查询(每次查询少一半数据)
法1:
import java.util.Scanner;
public class Demo06Binary {
public static void main(String[] args) {
int[] arr = {1,2,3,4,5,6,7};
int min = 0;
int max = arr.length-1;
int mid = (min+max)/2;
System.out.println("请输入想要查找的数:");
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
while (min<=max){
if (arr[mid]==n){
System.out.println("查找成功!,索引是"+mid);
break;
} else if (arr[mid]<n) {
min = mid+1;
mid = (min+max)/2;
}else {
max = mid-1;
mid = (min+max)/2;
}
}
if (min>max){
System.out.println("查找失败!");
}
}
}
法2:
import java.util.Scanner;
public class Demo07Binary {
public static void main(String[] args) {
int[] arr = {1,2,3,4,5,6,7};
System.out.println("请输入欲查询数字:");
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int result = Binary(n,arr);
if (result!=-1){
System.out.println("查询成功!索引是"+result);
}else {
System.out.println("查询失败!");
}
}
public static int Binary(int n,int[] arr){
int min = 0;
int max = arr.length-1;
int mid = 0;
while (min<=max){
mid = (min+max)/2;
if (arr[mid]<n){
min = mid+1;
} else if (arr[mid]>n) {
max = mid-1;
}else {
return mid;
}
}
return -1;
}
}
第五章 数组操作
1.对象数组:
需求:定义一个长度为3的数组,存储3个Person对象,遍历数组,将3个Person对象中的属性值获取出来
public class Person {
private String name;
private int age;
public Person(){
}
public Person(String name,int age) {
this.name = name;
this.age = age;
}
public void setName(String name){
this.name = name;
}
public String getName(){
return name;
}
public void setAge(int age){
this.age = age;
}
public int getAge(){
return age;
}
}
public class Demo01ObjectArray {
/*
定义一个长度为3的数组,存储3个Person对象,遍历数组,将3个Person对象中的属性值获取出来
*/
public static void main(String[] args) {
Person[] arr = new Person[3];
Person p1 = new Person("蒋敦豪",29);
Person p2 = new Person("鹭卓",29);
Person p3 = new Person("李耕耘",28);
arr[0] = p1;
arr[1] = p2;
arr[2] = p3;
/*
遍历
当i等于0时,arr[0]就是p1对象
当i等于1时,arr[1]就是p2对象
当i等于2时,arr[2]就是p3对象
*/
for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i].getName()+" "+arr[i].getAge());
}
}
}
练习1:
(1)定义学生类Student
声明姓名和成绩成员变量
(2)测试类ObjectArrayTest的main中创建一个可以装3个学生对象的数组,并且按照学生成绩排序,显示学生信息
public class Student {
private String name;
private int score;
public Student(){
}
public Student(String name,int score){
this.name = name;
this.score = score;
}
public void setName(String name){
this.name = name;
}
public void setScore(int score){
this.score = score;
}
public String getName(){
return name;
}
public int getScore(){
return score;
}
}
public class ObjectArrayTest {
public static void main(String[] args) {
Student[] arr1 = new Student[3];
arr1[0] = new Student("卓沅",100);
arr1[1] = new Student("赵小童",98);
arr1[2] = new Student("何浩楠",99);
boolean swapped = false;
for (int i = 0; i < arr1.length-1; i++) {
for (int j = 0; j < arr1.length-1-i; j++) {
if (arr1[j].getScore()<arr1[j+1].getScore()){
Student temp = arr1[j];
arr1[j] = arr1[j+1];
arr1[j+1] = temp;
swapped = true;
}
}
if (!swapped){
break;
}
}
for (int i = 0; i < arr1.length; i++) {
System.out.println(arr1[i].getName()+"..."+arr1[i].getScore());
}
}
}
第六章 方法参数
1.基本数据类型做方法参数传递
基本数据类型作为实参传递,传递的是值不是变量本身
方法运行,压栈保存
方法运行结束,弹栈 ->释放栈内存
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
}
}
2.引用数据类型做方法参数传递
引用数据类型作为方法参数传递时,传递的是地址值而不是具体的数据
public class Demo02Param {
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]);//20
System.out.println(arr[1]);//40
}
}
第七章 命令行参数(了解)
通过命令行给main方法的形参传递的实参称为命令行参数
第八章 其他操作
1.快速生成方法
1.初学者要求先定义在调用;不是初学者就可以先调用在定义方法
快捷键:Alt+回车
2.快速将一段代码抽取到一个方法中:
选中要抽取的方法,按 Ctrl + Alt + m
2.debug调试
1.概述:调试代码的一种手段
2.作用:能清楚的看到每个变量在代码执行过程中的变化,还可以找错
3.使用:在想要开始Debug的代码那一行最左边点击一下,出现红色小圆点(断点),右键点击Debug