Java入门第二周
前言
从零开始学Java的第二周
一、循环是什么?
在进行重复动作时需要不断编写同一段代码,代码的冗余度很高,循环可以简化代码,减少代码冗余。
1.for循环
for循环的格式:
for(初始化语句;条件表达式;步长/控制体语句){
循环体语句;
}
需要明确循环次数
for循环的特点:
for循环结束之后,不能在访问for中变量
如果我们要打印十次helloworld?
//原始的做法:
System.out.println("helloworld") ;
System.out.println("helloworld") ;
System.out.println("helloworld") ;
System.out.println("helloworld") ;
System.out.println("helloworld") ;
System.out.println("helloworld") ;
System.out.println("helloworld") ;
System.out.println("helloworld") ;
System.out.println("helloworld") ;
System.out.println("helloworld") ;
//使用循环:
for(int x = 0 ; x < 10 ; x ++){//x=0 ,0<10,1<10 9<10 x++ -- x = 10 10 < 10 (false)
System.out.println("helloworld") ;//1),2)....10)
}
用for循环输出三位数的水仙花数,并计算个数。
public class Narcissistic {
public static void main(String[] args) {
int num = 0;
for (int n = 100; n <= 999; n++) {
int b = n / 100; //取百位数
int s = n % 100 / 10; //取十位数
int g = n % 10; //取个位数
if (n == b * b * b + s * s * s + g * g * g) { //循环打印水仙花数
num++; //计数器
System.out.println(n);
}
}
System.out.println("共有" + num + "个水仙花数");
}
}
2.while循环
while循环格式:
初始化语句;
while(条件表达式){
循环体语句;
控制体语句/步长语句;
}
不明确循环次数的时候:使用while
while循环的特点:
循环结束,while循环仍然可以访问
写一个猜数字小游戏
import java.util.Scanner;
public class GuessNumber {
public static void main(String[] args) {
System.out.println("猎杀时刻到了,请你输入一个1-100的数字");
Scanner in = new Scanner(System.in);
int guessNumber;
int count = 0;
int number = (int) (Math.random() * 100) + 1;
while(ture){
guessNumber = in.nextInt();
count++;
if (guessNumber > number) {
System.out.println("偏大");
} else if (guessNumber < number) {
System.out.println("偏小");
} else {
System.out.println("恭喜你,猜对了,你一共猜了" + count + "次");
break;
}
}
}
}
3.do-while循环
do-while:优先循环体语句,即使条件不成立,循环体至少执行一次
do-while循环格式:
初始化语句;
do{
循环体语句;
控制体语句;
}while(条件表达式) ;
class DoWhile{
public static void main(String[] args){
//1-100之间的和
int sum = 0 ;
int x = 1 ;
do{
sum += x ;
x ++ ;
}while(x<=100) ;
//输出sum
System.out.println("1-100之间的和是:"+sum) ;
4.for循环嵌套
经典问题百钱买百鸡
public class BuyChicken {
public static void main(String[] args) {
for (int gonji = 0; gonji <= 33; gonji++) {
for (int muji = 0; muji <= 50; muji++) {
for (int xiaoji = 0; xiaoji <= 300; xiaoji++) {
if (gonji * 3 + muji * 2 + xiaoji == 100 && gonji + muji + xiaoji * 3 == 100) {
System.out.println("公鸡数量是:" + gonji + "\t" + "母鸡数量是:" + "\t" + muji + "\t" + "小鸡数量是:"
+ xiaoji * 3);
}
}
}
}
9*9的乘法表
public class MultiplicationTable {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int num = sc.nextInt();
for (int i = 1; i < num; i++) {
for (int j = 1; j < i + 1; j++)
System.out.print(j + "*" + i + "=" + (i * j) + "\t"+" ");
System.out.println();
}
}
}
5.跳转控制语句
break :结束中断,结束循环(不能单独使用)
在switch和循环中使用
return :很少单独使用,结合有具体返回值类型的方法使用!(方法?)
结束方法的;
continue:继续, 在循环中使用,结束当前循环,立即进入下一次循环
二、什么是方法?
一个代码块具有一个特定的功能,用{}包起来,需要时可以直接调用完成功能,这就是方法。
Java中定义方法的格式:
有具体返回值类型的方法的定义
固定格式:
public static 返回值类型 方法名(参数类型1 变量名1,参数类型2 变量名2....){
方法中的业务逻辑代码...
return 结果;
单独调用没有意义
可以输出调用或者赋值调用
针对某个功能代码块{} 没有具体的返回值类型
固定格式:
public static void 方法名(形式参数列表){
方法体中的内容:直接输出 或者进行其他操作;(不需要return语句了)
}
只能单独调用!
1.方法重载
方法重载(overload) :方法名相同,参数列表不同,与返回值无关
参数列表不同:
1)参数个数不同
2)参数类型不同
方法重载的目的:就是为了提高某个功能的扩展性
//以下就是方法重载的实例
public static int sum(int a,int b){
return a + b ;
}
public static int sum(int a,int b, int c){
return a + b + c ;
}
public static int sum(int a,int b,int c,int d){
return a + b + c + d ;
}
}
2.Java中的内存分配有哪些?
寄存器:程序无法控制(和计算机cpu有关系)
栈:存储都是局部变量(在方法定义中或者方法声明上)
堆:new出来的东西,创建对象 (里面存储:"成员变量")
方法区:有哪些方法--分别存储在哪个类中---xxx.class()
字节码文件区:class:存储字节码文件对象
静态区:static存储的静态成员
常量池:String "字符串就是一个常量" (在常用类中)
3.方法的形式参数问题
1.如果形参是基本数据类型或者String类型(特殊的引用类型)
它们作为形式参数,形式参数的改变不影响实际参数(String本质就是常量)
例如:
class ArgsDemo{
public static void main(String[] args){
//定义了两个变量
int a = 10 ;
int b = 20 ;
System.out.println("a:"+a+",b:"+b) ; //a:10,b:20
//定义了一个方法:没有具体返回值类型,void代替 直接输出
change(a,b) ;//10,20
System.out.println("a:"+a+",b:"+b) ;//10,20
//形式参数是基本数据类型 10,20
public static void change(int a,int b){
System.out.println("a:"+a+",b:"+b) ;//a:10,b:20
a = b ;
b = a+ b;
System.out.println("a:"+a+",b:"+b) ;
}
}
/*这时我们就会看到最下面的输出是20,40
但是调用方法下一行的输出依然没用发生变化 还是10,20.
因为方法的形参是基本数据类型,创建局部变量存放在栈内存,
栈内存随着方法的创建而开辟,随着方法结束而被系统释放,
其中数据的改变并没有保留下来
2.如果形参是引用数据类型
如果形式参数是数组类型(除String类型外),
实际参数传递:传递数组对象 :形式参数的改变会直接影响实际参数
int[] arr = {1,2,3,4,5} ;
System.out.println(arr[1]) ;
//重载的change方法
change(arr) ;
System.out.println(arr[1]) ;
}
//执行change方法
public static void change(int[] arr){
//形式参数是引用类型:数组 (实际参数传递:传递的空间地址值)
//遍历arr数组
for(int x = 0 ; x < arr.length ; x ++){
if(arr[x] %2 == 0){
arr[x] *= 2 ;
}
}
}
/*这时执行方法前后的输出值就发生变化了,所以形参的改变影响了实参
因为引用数据类型存在堆内存中,形参传递的是地址值,修改堆中的数值发生变
化,方法结束后,堆内存的改变被保留下,所以再次访问堆,数据已经发生改变
三、什么是数组?
能存储多个数据的容器,但是容器中的数据类型必须保持一致。
1.数组的定义格式
动态初始化
//给定了数组的长度,系统默认对元素进行初始化!
数据类型[] 数组名称 = new 数据类型[数组长度] ;
//或
数据类型 数组名称[] = new 数据类型[数组长度] ;
静态初始化
//给定了数组元素,进行初始化
int[] 数组名称 = {元素1,元素2,,,,,} ;
我们通过数组下标来访问数组中的元素,下标从0到数组长度减1。
2.数组的遍历
就是从数组的第一个元素数到最后一个元素,通常使用循环完成,完成特定功能。
正序遍历:
例如:打印一个数组a[]
public void print(int[] a) {
System.out.print("[");
for (int i = 0; i < a.length; i++) {
if (i < a.length - 1) {
System.out.print(a[i] + ",");
} else {
System.out.println(a[i] + "]");
}
}
逆序遍历:
例如:把一个数组a[ ],逆序输出
for (int i = a.length - 1; i >= 0; i--) {
System.out.print(a[i]);
}
1.数组反转
public static void Unsort(int[] arr){
//可以采用中间变量
/*
//第一次交换
int temp = arr[0] ;//将第一个元素赋值给中间变量
arr[0] = arr[arr.length-1-0] ; //将最后一个元素赋值给第一个元素
arr[arr.length-1-0] = temp ;//将中间变量的结果赋值给最后一个元素
//第二次交换
temp = arr[1] ; //将第二个元素
arr[1] = arr[arr.length-1-1] ; //将倒数第二个元素赋值给第二元素
arr[arr.length-1-1] = temp ;
*/
for(int x = 0 ; x < arr.length/2 ; x++){
//进行交互
int temp = arr[x]
arr[x] = arr[arr.length-1-x]
arr[arr.length-1-x] = temp
}
}
2.查询元素
//元素在数组中吗,如在输出下标,不在提示。
import java.util.Scanner;
public class Array {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);//创建键盘录入
int[] a = new int[5]; //创建数组动态初始化
System.out.println("请输入一个数组");
for (int i = 0; i < 5; i++) { //数组赋值
a[i] = in.nextInt();
}
System.out.println("请输入你要查询的数");
int b = in.nextInt();
int index = getIndex(a,b); //接收方法返回值
if (index < 0) { //if判断
System.out.println("你查询的数不存在");
} else {
System.out.println("你要找的元素的角标是:"+index);
}
}
public static int getIndex(int a[],int b) { //循环判断下标
for (int i = 0; i < a.length; i++) {
if (a[i] == b) {
System.out.println(i);
return i;
}
}
return -1;
}
}
3.3 数组的高级排序方式
3.3.1 冒泡排序
核心思想:
两两比较,较大的值往后放,第一次比较完毕,最大值出现在最大索引处
依次这样比较,可以得到排好序的数组
代码演示:
package DaySix;
public class BubbleSort2 {
public static void main(String[] args) {
int[] a = {43, 65, 3, 6, 76};
printArray printArray = new printArray();//创建对象
System.out.println("冒泡前:");
printArray.print(a);//调用打印方法
printArray.bubbleSort(a);//调用冒泡排序
System.out.println("冒泡后:");
printArray.print(a);//再次打印数组
}
}
class printArray {
public void bubbleSort(int[] a) { //冒泡排序的方法
for (int i = 0; i < a.length - 1; i++) {
for (int j = 0; j < a.length - i - 1; j++) {
if (a[j] > a[j + 1]) {
int temp = a[j];
a[j] = a[j + 1];
a[j + 1] = temp;
}
}
}
}
public void print(int[] a) { //打印数组的方法方便打印
System.out.print("[");
for (int i = 0; i < a.length; i++) {
if (i < a.length - 1) {
System.out.print(a[i] + ",");
} else {
System.out.println(a[i] + "]");
}
}
}
}
3.3.2 选择排序
核心思想:
索引值0的元素与后面的元素比较,小的替换,第一次循环结束最小值出现在最小索引处.
public void SelectSort(int[] a) { //选择排序的方法
for (int i = 0; i < a.length - 1; i++) {
for (int j = 1 + i; j < a.length; j++) {
if (a[i] > a[j]) {
int temp = a[i];
a[i] = a[j];
a[j] = temp;
}
}
}
四、什么是面向对象?
1.面向对象以及面向对象的思想特点
面向对象,简单来说就是创建类让类帮你完成各种功能,而你需要做一件事时,只需要调用已存在的类就可以。
面向的的思想特点:
1)更符号我们生活中是思想行为习惯
2)让复杂的事情简单化
3)我们从执行者变成了指挥者
面向对象的三大特征:
封装,继承,多态
面向对象的设计理念: 不断的去创建对象,使用对象,指挥对象做事情
2.类和对象的关系
类:能够描述现实世界真实事物的一组属性和行为的集合。
对象:就是用来描述客观事物的一个实体,有一组属性和方法构成。
对象具有成员属性和成员方法。
对象是类中的特定实例。
例如:定义一个手机类
/*
手机事物-----使用面向对象的方式: 定义手机类
品牌,价格,颜色,内存的属性
打电话,发短信,玩游戏,学习的行为
*/
class Phone{
//成员变量
String brand ; //品牌
int price ; //价格
String color ;//颜色
int memory ; //内存
//成员方法
public void callPhone(String toName){
System.out.println("给"+toName+"打电话") ;
}
public void sendMsg(){
System.out.println("可以使用手机发短信...") ;
}
public String playGame(String gameName){
return "可以玩"+gameName+"游戏" ;
}
public void study(String className){
System.out.println("学习"+className) ;
}
}
手机类的测试类:
class PhoneTest{
public static void main(String[] args){
//创建两个手机类对象
Phone p1 = new Phone() ;
Phone p2 = new Phone();
System.out.println(p1) ;
System.out.println(p2) ;
System.out.println(p1.brand+"---"+p1.price+"---"+p1.color+"---"+p1.memory) ;
System.out.println(p2.brand+"---"+p2.price+"---"+p2.color+"---"+p2.memory) ;
//赋值
p1.brand = "iphone12" ;
p1.price = 5999 ;
p1.color = "玫瑰金" ;
p1.memory=64 ;
System.out.println(p1.brand+"---"+p1.price+"---"+p1.color+"---"+p1.memory) ;
System.out.println("-----------------------------") ;
p2.brand = "锤子手机" ;
p2.price = 2999 ;
p2.color = "天空灰" ;
p2.memory= 32 ;
System.out.println(p2.brand+"---"+p2.price+"---"+p2.color+"---"+p2.memory) ;
//成员方法p1.方法名() ;
//p2.方法名() ;
}
}
3.成员变量和局部变量的区别
成员变量和局部变量的区别?
1)在程序中的书写位置不同
局部变量:
方法定义中或者方法声明上
成员变量:
在类中,成员方法外定义的变量
2)在内存中
局部变量:
在栈内存中
成员变量:
在堆内存中
3)生命周期不同
局部变量:
随着方法调用而存在,随着方法调用完毕而消失!
成员变量:
随着对象的创建而存在,随着对象创建完毕之后,不会立即消失,
需要等待GC(垃圾回收器空闲时候回收掉!)
GC算法----->标记算法
标记---清除
4)初始化不同
局部变量:
可以先定义,但是必须在使用之前必须赋值,否则:可能尚未初始化变量
成员变量:
可以不初始化,它存在系统默认初始化!(根据类型判定)
4.如果方法的形式参数是一个具体类
需要先创建类对应的对象,由对象取调用方法。
如下:
class Student{
//有一个成员方法:学习的方法
public void study(){
System.out.println("Good Good Study ,Day Day Up!!") ;
}
}
//定义一个StudentDemo类
class StudentDemo{
//有一个method成员方法
public void method(Student s){ //方法的形式参数是Student类型
//调用method 方法的时候:实际参数需要传递的是当前类的具体对象
//Student s = new Student();
s.study() ; //对象名.方法() ;
//stu.study() ;
}
}
//测试类
class StudentTest{
public static void main(String[] args){
//在测试类中访问StudentDemo类中的method方法?
//创建StudentDemo类对象
StudentDemo sd = new StudentDemo() ;
//sd.method(s) ;//找不到符号
//先去创建学生对象
Student stu = new Student() ;
sd.method(stu) ;
}
}
5.匿名对象是什么?
没有 名字的对象
格式:
new 类名() ;
匿名对象的特点:
可以作为参数进行传递
在开发中,匿名对象使用一次即可!
(因为没有栈内存变量指向堆内存地址,
直接是在堆内存开辟空间,使用完毕,立即被回收!)
例如:
class Student{
public void study(){
System.out.println("爱生活,爱Java,爱敲代码...") ;
}
}
//定义StudentDemo类
class StudentDemo{
public void method(Student student){
student.study() ;
}
}
//测试类
class NoNameObjectDemo{
public static void main(String[] args){
//方式1
StudentDemo sd2 = new StudentDemo() ;
sd2.method(new Student()) ;
System.out.println("------------------------------") ;
//链式编程
//一步走
new StudentDemo().method(new Student()) ;
}
}
6.封装是什么?
就是将一个类(能够描述现实世界事物的)的属性细节隐藏(成员变量私有化),保证数据的安全性,从而对外提供公共的访问方法
例如:
class Student{
//属性私有化
private String name ;//姓名
private int age ; //年龄
private String gender ;//性别
//被私有的变量和方法只能通过本类进行访问,外界类不能访问
//对外提供公共的访问方法
//给学生的姓名赋值
public void setName(String n){
name = n ;
}
//获取学生的姓名
public String getName(){
return name ;
}
}
给属性赋值的时候:局部变量隐藏了成员变量:名称都是一样的
Java此时提供关键字this:解决局部变量隐藏了成员变量
this.成员变量名 = 局部变量;
this:就是代表当前类的对象的地址值引用!
让我再演示一遍封装一个手机类
class Phone{
//成员变量:私有化
private String brand ; //品牌
private int price ; //价格
private String color ; //颜色
private String memory ;//内存 "G"
//公共访问方法:setXXX()/getXXX()方法为私有的成员进行赋值和获取值
//给品牌属性赋值
//public void setBrand(String b){
public void setBrand(String brand){//品牌 "华为mate30"
//brand = b ;
this.brand = brand ;//"华为mate30"
}
//获取品牌的值
public String getBrand(){
return brand ; //getXXX()---隐藏this
//return this.brand ;
}
//给价格赋值
//public void setPrice(int p){
public void setPrice(int price){
//price = p;
this.price = price ;
}
//获取价格
public int getPrice(){
return price ;
}
//给手机颜色赋值
//public void setColor(String c){
public void setColor(String color){
//color = c ;
this.color = color;
}
//获取颜色
public String getColor(){
return color ;
}
//给手机内存赋值
//public void setMemory(String m){
public void setMemory(String memory){
//memory = m ;
this.memory = memory ;
}
//获取内存
public String getMemory(){
return memory ;
}
//其他成员方法
//打电话
public void call(String toName){
System.out.println("可以给"+toName+"打电话了...") ;
}
//学习
public void study(){
System.out.println("使用手机可以学习任何技术...") ;
}
}
//测试类
class PhoneTest{
public static void main(String[] args){
//创建手机类对象
Phone p = new Phone() ;
//通过setXXX()属性赋值
p.setBrand("华为mate30") ;
p.setPrice(5999) ;
p.setColor("天空灰") ;
p.setMemory("128G") ;
//输出
System.out.println("手机品牌是:"+p.getBrand()+",价格为:"+p.getPrice()+","
+"颜色是:"+p.getColor()+",内存大小为:"+p.getMemory()) ;
p.call("对象") ;
p.study() ;
}
}
7.构造方法
什么是构造方法?
1)构造方法名和类名一致
2)没有具体的返回值类型
3)连void都没有
构造方法的目的:为了给类的成员的一些数据进行初始化
代码演示如下:
class Student{
private String name ;//姓名
private int age ; //年龄
//定义一个构造方法?
//无参构造方法
public Student(){
}
//定义有参构造方法(带一个String类型的参数)
public Student(String name){
this.name = name ;
}
}
注意事项
1.当我们书写某个类中代码的时候,没有给这个类提供任何构造方法,那么系统
会默认提供一个无参构造方法
2.如果我们提供了一种有参构造方式那么系统就不会在为我们提供默认的无参构造方式
Tips:建议永远提供一个无参构造方式
构造方式的目的就是为成员变量提供初始化。
给成员变量赋值的两种方式:
一、公共的访问方法Set(XXX)
二、构造方式
8.一个标准类
标准类其中包括有参无参构造,GetSet方法,还包括其他成员方法。
例如:
class Student{
//属性私有化
private String name ;//姓名
private int age ; //年龄
private String gender ;//性别
private String sid ; //学生学号
//无参构造方法
public Student(){
}
//有参构造方法
public Student(String name,int age,String gender,String sid) {
//赋值
this.name = name ;
this.age = age ;
this.gender = gender ;
this.sid = sid ;
}
//提供setXXX()/getXXX()方法
//给姓名赋值
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 void setGender(String gender){
this.gender = gender ;
}
//获取性别
public String getGender(){
return gender ;
}
//给学号赋值
public void setSid(String sid){
this.sid = sid ;
}
//获取学号
public String getSid(){
return sid ;
}
//吃
public void eat(){
System.out.println("学生吃营养餐...") ;
}
//睡
public void sleep(){
System.out.println("学习累了就需要休息") ;
}
//学习
public void study(){
System.out.println("学习JavaSE...") ;
}
}