一.數組
1.數組的定義
格式:
1.數組存儲的數據類型[] 數組名字;
2.數組存儲的數據類型 數組名字[];
- 方式一 :
數組動態初始化
1.定義:數組動態初始化就是只給定數組的長度,由系統給出默認初始化值
2.格式:數組存儲的數據類型[] 數組名字 = new 數組存儲的數據類型[長度];
舉例:
定義可以存儲3個整數的數組容器,代碼如下:
1.int[] arr = new int[3];
- 方式二 :
數組靜態初始化
1.定義:在創建數組時,直接確定數組元素
2.標準格式:數據類型[] 數組名 = new 數據類型[]{元素1,元素2,元素3...};
舉例:
定義存儲1,2,3,4,5整數的數組容器。代碼如下:
1.int[] arr = new int[]{1,2,3,4,5};
簡化格式:
數據類型[] 數組名 = {元素1,元素2,元素3...};
舉例:
定義存儲1,2,3,4,5整數的數組容器。代碼如下:
1.int[] arr = {1,2,3,4,5};
2.數組的訪問
- 索引: 每一個存儲到數組的元素,都會自動的擁有一個編號,從0開始,這個自動編號稱為數組索引(index),可以通過數組的索引訪問到數組中的元素。
- 格式:
1.數組名[索引]
- 數組的長度屬性: 每個數組都具有長度,而且是固定的,Java中賦予了數組的一個屬性,可以獲取到數組的長度,語句為:
數組名.length
,屬性length的執行結果是數組的長度,int類型結果。由次可以推斷出,數組的最大索引值為數組名.length-1
。
public static void main(String[] args) {
int[] arr = new int[]{1,2,3,4,5};
//打印數組的屬性,輸出結果是5
System.out.println(arr.length);
}
- 索引訪問數組中的元素:
1.數組名[索引]=數值,為數組中的元素賦值
2.變量=數組名[索引],獲取出數組中的元素
public static void main(String[] args) {
//定義存儲int類型數組,賦值元素1,2,3,4,5
int[] arr = {1,2,3,4,5};
//為0索引元素賦值為6
arr[0] = 6;
//獲取數組0索引上的元素
int i = arr[0];
System.out.println(i);
//直接輸出數組0索引元素
System.out.println(arr[0]);
}
二.數組原理內存圖
1.內存概述:
內存是計算機中的重要原件,臨時存儲區域,作用是運行程序。我們編寫的程序是存放在硬盤中的,在硬盤中的程序是不會運行的,必須放進內存中才能運行,運行完畢后會清空內存。
Java虛擬機要運行程序,必須要對內存進行空間的分配和管理。
2.Java虛擬機的內存劃分:
為了提高運算效率,就對空間進行了不同區域的劃分,因為每一片區域都有特定的處理數據方式和內存管理方式。
- JVM的內存劃分:
區域名稱 | 作用 |
---|---|
寄存器 | 給CPU使用,和我們開發無關。 |
本地方法棧 | JVM在使用操作系統功能的時候使用,和我們開發無關。 |
方法區 | 存儲可以運行的class文件。 |
堆內存 | 存儲對象或者數組,new來創建的,都存儲在堆內存。 |
方法棧 | 方法運行時使用的內存,比如main方法運行,進入方法棧中執行。 |
1.堆內存用途:存放的是對象,垃圾收集器就是收集這些對象,然后根據GC算法回收。
2.非堆內存用途:永久代, 也稱為方法區,存儲程序運行時長期存活的對象,比如類的元數據、方法、常量、屬性等。
注意:main()方法先入方法棧逐步執行主方法中的程序,如果有使用其他方法,其他方法入棧,直到main()方法結束。
image
-
成員變量和局部變量的區別:image
3.數組在內存中的存儲
-
一個數組內存圖:
public static void main(String[] args) {
int[] arr = new int[3];
System.out.println(arr);//[I@5f150435
}
以上方法執行,輸出的結果是[I@5f150435,這個是什么呢?是數組在內存中的地址。new出來的內容,都是在堆內存中存儲的,而方法中的變量arr保存的是數組的地址。
輸出arr[0],就會輸出arr保存的內存地址中數組中0索引上的元素
-
當兩個變量指向同一個數組:
public class ArrayDemo02 {
public static void main(String[] args) {
//定義數組
int[] arr = new int[3];
//對數組進行賦值操作
for (int i = 0; i < arr.length; i++) {
arr[i] = 6;
}
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + "\t");
}
System.out.println();
//定義數組變量arr2,將arr的地址賦給arr2
int[] arr2 = arr;
//修改arr2的第二個元素
arr2[1] = 8;
System.out.println(arr[1]);
//遍歷arr2
for (int i = 0; i < arr2.length; i++) {
System.out.print(arr2[i] + "\t");
}
}
}
-
兩個變量指向一個數組:
public static void main(String[] args) {
// 定義數組,存儲3個元素
int[] arr = new int[3];
//數組索引進行賦值
arr[0] = 5;
arr[1] = 6;
arr[2] = 7;
//輸出3個索引上的元素值
System.out.println(arr[0]);
System.out.println(arr[1]);
System.out.println(arr[2]);
//定義數組變量arr2,將arr的地址賦值給arr2
int[] arr2 = arr;
arr2[1] = 9;
System.out.println(arr[1]);
}
三.數組操作的常見問題
1.數組越界異常
觀察一下代碼,運行后會出現什么結果。
public static void main(String[] args) {
int[] arr = {1,2,3};
System.out.println(arr[3]);
}
創建數組,賦值3個元素,數組的索引就是0,1,2,沒有3索引,因此我們不能訪問數組中不存在的索引,程序運行后,將會拋出 ArrayIndexOutOfBoundsException
數組越界異常。在開發中,數組的越界異常是不能出現
的,一旦出現了,就必須要修改我們編寫的代碼。
2. 數組空指針異常
觀察一下代碼,運行后會出現什么結果。
public static void main(String[] args) {
int[] arr = {1,2,3};
arr = null;
System.out.println(arr[0]);
}
arr = null
這行代碼,意味著變量arr將不會在保存數組的內存地址,也就不允許再操作數組了,因此運行的時候會拋出NullPointerException
空指針異常。在開發中,數組的越界異常是不能出現的,一旦出現了,就必須要修改我們編寫的代碼。
空指針異常在內存圖中的表現:
解決方案:
給數組一個真正的堆內存空間引用即可!
四. 數組練習
1. 數組遍歷【重點】
- 數組遍歷: 就是將數組中的每個元素分別獲取出來,就是遍歷。遍歷也是數組操作中的基石。
int[] arr = { 11, 22, 33, 44, 55 };
System.out.println(arr[0]);
System.out.println(arr[1]);
System.out.println(arr[2]);
System.out.println(arr[3]);
System.out.println(arr[4]);
}
以上代碼是可以將數組中每個元素全部遍歷出來,但是如果數組元素非常多,這種寫法肯定不行,因此我們需要改造成循環的寫法。數組的索引是0
到lenght-1
,可以作為循環的條件出現。
public static void main(String[] args) {
int[] arr = { 11, 22, 33, 44, 55 };
for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i]);
}
}
2.數組獲取最大值元素
-
最大值獲取:從數組的所有元素中找出最大值。
-
實現思路:
1.定義變量,保存數組0索引上的元素
2.遍歷數組,獲取出數組中的每個元素
3.將遍歷到的元素和保存數組0索引上值的變量進行比較
4.如果數組元素的值大于了變量的值,變量記錄住新的值
5.數組循環遍歷結束,變量保存的就是數組中的最大值
代碼如下:
public static void main(String[] args) {
int[] arr = { 5, 15, 2000, 10000, 100, 4000 };
//定義變量,保存數組中0索引的元素
int max = arr[0];
//遍歷數組,取出每個元素
for (int i = 0; i < arr.length; i++) {
//遍歷到的元素和變量max比較
//如果數組元素大于max
if (arr[i] > max) {
//max記錄住大值
max = arr[i];
}
}
System.out.println("數組最大值是: " + max);
}
3.對數組進行反轉
- 方法一:
public static void main(String[] args) {
int[] arr = new int[]{1,2,3,4,5};
int[] arr2 = new int[5];
for (int i = 0; i < arr.length; i++) {
arr2[i] = arr[arr.length-i-1];
}
for (int i = 0; i < arr.length; i++) {
System.out.print(arr2[i] + "\t");
}
}
- 方法二:
public static void main(String[] args) {
int[] arr = new int[]{1,2,3,4,5};
for (int i = 0; i < arr.length/2; i++) {
int temp = arr[i];
arr[i] = arr[arr.length-i-1];
arr[arr.length-i-1] = temp;
}
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + "\t");
}
}
- 方法三:
public static void main(String[] args) {
/**
* for (初始化條件1,初始化條件2; 循環條件; 步進運算1,步進運算2)
* 定義 min = 0 最小索引值, max = arr.length-1 最大索引值
*/
int[] arr = new int[]{1,2,3,4,5};
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]);
}
}
4.數組作為方法的參數進行傳遞
public class ArrayDemo05 {
public static void main(String[] args) {
sayHello("劉柏廷");
int[] arr = {1,3,5,7,9};
printArray(arr);
}
public static void sayHello(String name){
System.out.println("Hello " + name);
}
//之前我們看到的方法都是基本數據類型作為參數
// 使用數組作為方法的參數 public static void printArray(形參(數據類型) 實參(變量值)){}
public static void printArray(int[] arr){
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + "\t");
}
}
}
5.數組作為方法的返回值
public class ArrayDemo06 {
public static void main(String[] args) {
int[] arr = getArray(); //返回的是地址,而不是具體的值
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + "\t");
}
}
public static int[] getArray(){
int[] arr = {1,2,3,4,5};
//返回數組的地址,返回給調用者
return arr;
}
}
6.
public class ArrayDemo07 {
public static void main(String[] args) {
int a = 1;
int b = 2;
System.out.println(a);
System.out.println(b);
change(a,b);
System.out.println(a);
System.out.println(b);
int[] arr = {1,2,3};
System.out.println(arr[0]);
changeArray(arr);
System.out.println(arr[0]);
}
public static void change(int a,int b){
a = a + b;
b = b + a;
}
public static void changeArray(int[] arr){
arr[0] = 200;
}
}
五.面向對象編程
- 對象:泛指現實中一切的事物,每個事物都有自己的【屬性】和【行為】
- 強調:通過調用對象的行為去實現功能,而不是自己一步步去實現
舉例:洗衣服:1.面向過程:把衣服脫掉-->盆-->加水-->泡-->洗。。。(強調步驟)2.面向對象:把衣服脫掉-->打開全自動洗衣機-->放衣服-->開關-->晾衣服(強調對象) - 面向對象特點:將復雜的事情簡單化,我們從執行者變成了指揮者(完成一個項目花錢雇人完成而不是自己做)
- 面向對象包含三大基本特征:封裝,繼承,多態
-
類和對象
1.類
- 概念:類是可以看成一類事物的模板,在面向對象編程中,使用屬性和行為來描述類
-在現實中:屬性:該事物的狀態信息; 行為:該事物能干什么 - 類在java中的定義:現實中的一類事物
- 屬性:事物的狀態信息,行為:能干啥
- java和現實是一致的
成員變量:對應的事物的屬性,成員方法:對應事物的行為
成員變量:和之前定義變量一樣,只不過位置變了, 在類中, 方法外
成員方法:只不過我們要將以前 方法static去掉
public class 類名{
//成員變量
//成員方法
}
2.對象
- 概念:對象是一類事物的具體體現
- 對象是類的一個實例,對象就必然具備該類事物的屬性和行為
舉例:貓類(屬性:tom 5kg 2yearsOld black 行為:跑,蹦跶,喵喵叫)
3.類與對象的關系
- 類是對一類事物的描述,抽象的. 對象是一類事物的實例,具體的
- 類是對象的模板,對象是類的實體
案例一:創建一個學生類
1.學生類
// 成員變量
String name;// 姓名
int age; // 年齡
// 成員方法
// 愛學習的方法
public void study(){
System.out.println("Good Good Study, Day Day Up!");
}
// 吃飯的方法
public void eat(){
System.out.println("學習餓了就要吃飯");
}
}
2.學生類的測試類
public class Test01_Student {
// 類的使用
// Java中通過創建對象去使用類
// 格式:
// 類名 對象名 = new 類名()
// 返回值類型 具體的對象名字 = new 類();
// 我們通過對象去訪問類中的成員
// 對象名.成員變量
// 對象名.成員方法();
public static void main(String[] args) {
// 調用 學生類
// 1.創建類,類名 對象名 = new 類名()
Student s = new Student();
// 2.打印這個對象
System.out.println(s);// com.neusoft.Student@1b6d3586 包名+16地址
// 3.訪問其中的成員變量
System.out.println("姓名"+s.name); // null
System.out.println("姓名"+s.age); // 0
System.out.println("----------------------------");
// 4、給成員變量進行賦值
s.name = "薰悟空";
s.age = 500;
// 5、再次輸出變量
System.out.println("姓名"+s.name); // "薰悟空";
System.out.println("姓名"+s.age); // 500;
System.out.println("----------------------------");
// 6、調用成員方法
s.study();
s.eat();
}
案例二:創建一個電話類
1.電話類
public class Test02_Phone {
public static void main(String[] args) {
//創建對象
Phone phone = new Phone();
//輸出成員變量
System.out.println(phone.brand);
System.out.println(phone.color);
System.out.println(phone.Price);
//成員變量賦值
phone.brand = "小米";
phone.color = "黃色";
phone.Price = 3888;
//再次輸出
System.out.println(phone.brand);
System.out.println(phone.color);
System.out.println(phone.Price);
//調用打電話方法
phone.phone("劉柏廷");
//調用發短信方法
phone.sendMessage();
show(phone);
}
public static void show(Phone p){
System.out.println(p.brand + p.color + p.Price);
}
}
2.電話類的測試類
public class Phone {
//屬性:品牌,價格,顏色
String brand;
int Price;
String color;
//方法:打 name 電話,發短信
public void phone(String name){
System.out.println("給" + name + "打電話");
}
public void sendMessage(){
System.out.println("發短信");
}
}
六.封裝
封裝實際上是將屬性封裝起來,屬性變為私有的,要提供公有的方法對其進行訪問
private 代表最小權限
可以修飾成員變量和成員方法
被private修飾的成員變量和成員方法,只有在本類才能訪問
案例:建立一個學生類,通過方法訪問及改變成員變量
測試:
public class Test03_StudentInfo {
public static void main(String[] args) {
StudentInfo studentInfo = new StudentInfo();
System.out.println(studentInfo.getName());
studentInfo.setName("劉柏廷");
System.out.println(studentInfo.getName());
}
}
定義一個StudentInfo:
public class StudentInfo {
private String name;
private int age;
//為成員方法提供公有的get,set方法(訪問,修改)
public String getName(){
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge(){
return age;
}
public void setAge(int age){
this.name = name;
}
}
注意:
這里this 的含義:
this代表所在類的當前對象的引用(地址值),即對象自己的引用
方法被哪個對象調用,方法中的this就代表哪個對象,即誰在調用,this就代表誰(StudentInfo)