Javase基礎(二)——數據類型
Javase基礎(二)——數據類型和運算
常量
什麼是常量:在程序執行的過程中其值不可以發生改變
常量的分類
- 字面值常量 5, 10 ,99 之類的
- 自定義常量(面向對象部分講) final PI=3.14159
- 字面值常量的分類
- 字符串常量 用雙引號括起來的內容
"avadsfasdfasdf"
- 整數常量 所有整數
- 小數常量 所有小數
- 字符常量 用單引號括起來的內容,裏面只能放單個數字,單個字母或單個符號(注意,單引號裏面什麼也不放是不行的)
- 布爾常量 較爲特殊,只有true和false
- 空常量 null(當數組引用屬於局部變量且未初始化時候)
- 字符串常量 用雙引號括起來的內容
進制概述和二,八,十六進制
進制:就是進位制,是人們規定的一種進位方法。 對於任何一種進制–X進制,就表示某一位置上的數運算時是逢X進一位。二進制就是逢二進一,八進制是逢八進一,十進制是逢十進一,十六進制是逢十六進一。
不同進製表現同一個數據的形式特點:進制越大,表現形式越短
-
二進制的數據表現形式
由0,1組成。以0b(b可以大寫也可以小寫)開頭(JDK1.7版本可以表示二進制了)
-
八進制的數據表現形式
由0,1,…7組成。以0開頭
-
十進制的數據表現形式
由0,1,…9組成。整數默認是十進制的
-
十六進制的數據表現形式
由0,1,…9,a,b,c,d,e,f(大小寫均可)。以0x開頭
進制轉換
- 任意進制到十進制的轉換原理
- 係數:就是每一位上的數據。
- 基數:X進制,基數就是X。
- 權:在右邊,從0開始編號,對應位上的編號即爲該位的權。
- 結果:把係數*基數的權次冪相加即可。
- 十進制到任意進制的轉換
-
除積倒取餘法
-
8421碼
8421碼是中國大陸的叫法,8421碼是BCD代碼中最常用的一種。在這種編碼方式中每一位二值代碼的1都是代表一個固定數值,把每一位的1代表的十進制數加起來,得到的結果就是它所代表的十進制數碼。
通過8421碼的方式進行二進制和十進制的相互轉換
二進制到八進制的簡易方式:三個二進制數爲一組
二進制到十六進制的簡易方式:四個二進制數爲一組
-
源碼、反碼、補碼
原碼
- 就是二進制定點表示法,即最高位爲符號位,“0”表示正,“1”表示負,其餘位表示數值的大小。
- 通過一個字節,也就是8個二進制位表示+7和-7
- 0(符號位) 0000111
- 1(符號位) 0000111
反碼
- 正數的反碼與其原碼相同;負數的反碼是對其原碼逐位取反,但符號位除外。
補碼
計算機計算時候都是以補碼形式運算的
- 正數的補碼與其原碼相同;負數的補碼是在其反碼的末位加1。
例子:
已知原碼求補碼
0b10110100 原
0b11001011 反//符號位不變
0b11001100 補
已知補碼求原
0b11101110 補
0b11101101 反
0b10010010 原
變量的概述及格式
變量:在程序執行的過程中,在某個範圍內其值可以發生改變的量,用來不斷的存放同一類型的常量,並可以重複使用
格式:數據類型 變量名 = 變量值;
基本數據類型佔用字節數
boolean 1
byte 1
char 2
short 2
int 4
float 4
long 8
double 8
變量相加和常量相加的區別
- 面試題:看下面的程序是否有問題,如果有問題,請指出並說明理由。
byte b1 = 3;
byte b2 = 4;
byte b3 = b1 + b2;
從兩方面去回答這個題
- b1和b2是兩個變量,變量裏面存儲的值都是變化的,所以在程序運行中JVM是無法判斷裏面具體的值
- byte類型的變量在進行運算的時候,會自動類型提升爲int類型
byte b4 = 3 + 4;
- 3和4都是常量,java有常量優化機制,就是在編譯的的時候直接把3和4的結果賦值給b4了
數據類型
Java語言是強類型語言,對於每一種數據都定義了明確的具體數據類型,在內存中分配了不同大小的內存空間
分類
-
基本數據類型
-
引用數據類型
-
其他
基本數據類型分類(4類8種)
-
整數型
- byte 佔一個字節 -128到127
- short 佔兩個字 -215~215-1
- int 佔四個字節 -231~231-1
- long 佔八個字節 -263~263-1
-
浮點型
- float 佔四個字節 -3.403E38~3.403E38 單精度(輸入浮點型數值末尾需要加上f/F)
- double 佔八個字節-1.798E308~1.798E308 雙精度(小數類型默認爲double)
-
字符型
- char 佔兩個字節 0~65535(char類型數據參與運算會自動提升爲int)
-
布爾型
-
boolean
boolean理論上是佔八分之一個字節,因爲一個開關就可以決定是true和false了,但是java中boolean類型沒有明確指定他的大小
不參與運算
-
類型 | ||||
---|---|---|---|---|
整型 | byte | short | int | long |
浮點 | float | double | ||
布爾 | boolean | |||
字符 | char |
字符和字符串
ASCII輸出:System.out.println('a');
字符類型與整數相加爲ASCII字符號加整數:System.out.println('a'+1);
ASCII碼錶,記住三個值:
- ‘0’ 48
- ‘A’ 65
- ‘a’ 97
字符串與其他類型相加等於在字符串後加上字符
System.out.println("hello"+'a'+1);
System.out.println('a'+1+"hello");
在有字符串參與中被稱爲字符串連接符
System.out.println("5+5="+5+5);
System.out.println(5+5+"=5+5");
char數據類型
char c = 97; 0到65535
Java語言中的字符char可以存儲一箇中文漢字。因爲Java語言採用的是Unicode編碼。Unicode編碼中的每個字符佔用兩個字節。中文也是佔的兩個字節。
佔用空間
類型 字節數 數據位 默認值 範圍
boolean 1 8 false [true,false]
byte 1 8 0 [-128,127]
char 2 16 '\u0000' [0,2^16]或['\u0000','\uffff']
short 2 16 0 [-2^15,2^15-1]
int 4 32 0 [-2^31,2^31-1]
float 4 32 0.0f [-3.4*10^38,-1.4*10^-45]U[1.4*10^-45,3.4*10^38]
long 8 64 0 [-2^63,2^63-1]
double 8 64 0.0d ...
long與float的取值範圍誰大誰小
進行混合運算的時候,byte,short,char不會相互轉換,都會自動類型提升爲int類型,其他類型進行混合運算的是小的數據類型提升爲大的
- byte,short,char(這三個混合運算也是轉換爲int) – int – long – float – double
- long: 8個字節
- float:4個字節
- IEEE754: 4個字節是32個二進制位,1位是符號位, 8位是指數位,00000000 11111111,0到255,1到254,-126到127,23位是尾數位,每個指數位減去127
結論:
-
它們底層的存儲結構不同。
-
float表示的數據範圍比long的範圍要大
long:2^63-1
float:3.410^38 > 210^38 > 28^38 = 22338 = 2*2^114 > 2^63-1
轉義字符
\f 下一頁
\b 退格
\r 回車
\n 換行
\t 製表
\uxxxx 十六進制unicode字符
\ddd 八進制unicode字符
自動類型轉換
byte-->short-->char-->int-->long-->float-->double
boolean
類型不能自動類型轉換
字符串與基本類型轉換
XXX.parseXXX(String s) //實現將字符串類型轉爲任意基本類型
小數準確運算
import java.math.BigDecimal;
public class Test {
public static void main(String[] args) {
System.out.println(0.05+0.01); //0.060000000000000005
BigDecimal bd1=new BigDecimal(0.05);
BigDecimal bd2=new BigDecimal(0.01);
System.out.println(bd1.add(bd2)); //0.06000000000000000298372437868010820238851010799407958984375
BigDecimal bd3=new BigDecimal("0.05");
BigDecimal bd4=new BigDecimal("0.01");
System.out.println(bd3.add(bd4)); //0.06
}
}
注意事項
- 作用域問題:同一個區域不能使用相同的變量名
- 初始化值問題:局部變量在使用之前必須賦值(方法內)
- 一條語句可以定義幾個變量:int a,b,c…;
隱式轉換
- int + int 結果爲int
- byte + int 結果爲int
Java中的默認轉換規則:取值範圍小的數據類型與取值範圍大的數據類型進行運算,會先將小的數據類型提升爲大的,再運算
強制轉換
強制轉換問題
- int a = 10;
- byte b = 20;
- b = a + b;
強制轉換的格式,括號不能省略
- b = (byte)(a + b); (強轉後的二進制都是按照補碼來計算)
強制轉換的注意事項:如果超出了被賦值的數據類型的取值範圍得到的結果會與你期望的結果不同(環形數值圈)而強轉相當於截取,兩種是不同
算術運算符
算術運算符,賦值運算符,比較(關係或條件)運算符,邏輯運算符,位運算符,三目(元)運算符
- +,-,*,/,%,++,–
注意事項:
- +號在java中有三種作用,代表正號,做加法運算,字符串的連接符
- 整數相除只能得到整數。如果想得到小數,必須把數據變化爲浮點數類型
- /獲取的是除法操作的商,%獲取的是除法操作的餘數
- %運算符
- 當左邊的絕對值小於右邊絕對值時,結果是左邊
- 當左邊的絕對值等於右邊或是右邊的倍數時,結果是0
- 當左邊的絕對值大於右邊絕對值時,結果是餘數
- %運算符結果的符號只和左邊有關係,與右邊無關
- 任何一個正整數%2結果不是0就是1可以用來當作切換條件
算術運算符++和–
- ++,–運算符的作用
- 自加(++)自減(–)運算
- ++:自加。對原有的數據進行+1
- –:自減。對原有的數據進行-1
eg:
int a = 10;
int b = 10;
int c = 10;
a = b++; //a=10,b=11
c = --a; //c=9,a=9
b = ++a; //b=10,a=10
a = c--; //a=9,c=8
eg:
int x = 4;
int y = (x++)+(++x)+(x*10);
//x=6,y=70
eg:
byte b = 10;
b++; //有機制
b = b + 1; //報錯,b是byte不能接收int
賦值運算符
-
基本的賦值運算符:=
- 把=右邊的數據賦值給左邊。
-
擴展的賦值運算符:+=,-=,*=,/=,%=
- += 把左邊和右邊做加法,然後賦值給左邊。
eg:
short s=1;s = s+1; //int賦值給short,溢出錯誤
short s=1;s+=1; //有機質
關係運算符
==,!=,>,>=,<,<=
注意事項:
-
無論你的操作是簡單還是複雜,結果是boolean類型。
-
“==“不能寫成”=”。
邏輯運算符
- & | ^ !
- && || (短路運算符)
注意事項:
- 邏輯運算符一般用於連接boolean類型的表達式或者值。
- 表達式:就是用運算符把常量或者變量連接起來的符合java語法的式子。
- 算術表達式:a + b
- 比較表達式:a == b(條件表達式)
&邏輯與:有false則false。
|邏輯或:有true則true。
^邏輯異或:相同爲false,不同爲true。
!邏輯非:非false則true,非true則false。特點:偶數個不改變本身。
短路運算區別
最終結果一樣。&&具有短路效果。左邊是false,右邊不執行。&是無論左邊是false還是true,右邊都會執行,同理||和|的區別同上。開發中使用短路運算比較好,但是還是要看情況而定。
位運算符
& | ^ ~ >> >>> <<
- &:有0則0
- |:有1則1
- ^:相同則0,不同則1
- :按位取反(求一個數x的相反數格式:X+1)
位異或運算符的特點
一個數據對另一個數據位異或兩次,該數本身不變。
邏輯運算符:運算布爾量
位運算符:運算數值量
可以用來實現兩個數的交換
int x,y;
x=x^y;
y=x^y;
x=x^y;
<<
:左移 左邊最高位丟棄,右邊補齊0,相當於×2
>>
:右移 最高位是0,左邊補齊0;最高爲是1,左邊補齊1,相當於÷2
>>>
:無符號右移 無論最高位是0還是1,左邊補齊0
eg:最有效率的算出2 * 8的結果(2<<3)
三元運算符
三元運算符的格式:(關係表達式) ? 表達式1 : 表達式2;
max=a>b?b;
Boolean x=a==b?trufalse;
max=a>b?(a>c?c):(b>c?c);
鍵盤錄入
鍵盤錄入練習:鍵盤錄入兩個數據,獲取這兩個數據中的最大值03.10_Java語言基礎(鍵盤錄入的練習2)(掌握)
03.11_Java語言基礎(順序結構語句)(瞭解)
import java.util.Scanner;
class LuRuDemo1
{
public static void main(String[] args)
{
Scanner sc=new Scanner(System.in);
System.out.println("請分別輸入兩個整數!");
int x=sc.nextInt();
int y=sc.nextInt();
int max;
max=(x>y)? x:y;
System.out.println("最大的數是"+max);
}
}
流程控制語句:可以控制程序的執行流程。
流程控制語句的分類
- 順序結構
- 選擇結構
- 循環結構
執行流程:
- 從上往下,依次執行。
選擇結構
if語句。。。balabala我就不介紹了
import java.util.Scanner;
class If_Else {
public static void main(String[] args) {
int x;
Scanner sc=new Scanner(System.in);
System.out.println("輸入一個一百以內數字");
x=sc.nextInt();
if (x>100|x<0) {
System.out.println("成績輸入錯誤");
}else if (x>=90) {
System.out.println("優");
}else if (x>=80) {
System.out.println("良");
}else if (x>=70) {
System.out.println("中");
}else if (x>=60) {
System.out.println("及");
}else
System.out.println("差");
}
}
switch語句:
switch表達式:能自動類型提升爲int的都可以作爲其表達式內容,long不可以,String可以。
default一定是最後執行。
import java.util.Scanner;
class Day {
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
System.out.println("請輸入1-7的一個數字");
int x=sc.nextInt();
switch(x){
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;
case 6:
System.out.println("星期六");
break;
case 7:
System.out.println("星期日");
break;
default:
System.out.println("格式錯誤");
}
}
}
注意:
- case後面只能是常量,不能是變量,而且,多個case後面的值不能出現相同的
- default可以省略,但是不建議
- break漏寫會出現一個現象:case穿透。(case 穿透和default穿透)
- default可以在任意位置。但是建議在最後。依然是最後執行。
- switch語句的結束條件
- 遇到break就結束了
- 執行到switch的右大括號就結束了
循環結構
for,while,do…while
輸出10次helloworld
class HelloWorld {
public static void main(String[] args){
for(int i=1;i<=10;i++) {
System.out.println(“helloworld”);
}
}
}
需求:在控制檯輸出所有的”水仙花數”,所謂的水仙花數是指一個三位數,其各位數字的立方和等於該數本身。舉例:153就是一個水仙花數。153 = 111 + 555 + 333 = 1 + 125 + 27 = 153
class Flower {
public static void main(String[] args) {
int a1,a2,a3,count=0;
for (int i=100;i<1000 ;i++ ) {
a1=i%10; //個
a2=i/10%10; //十
a3=i/100; //百
if (i==a1*a1*a1+a2*a2*a2+a3*a3*a3) {
System.out.println(i);
count++;
}
}
System.out.println(count);
}
}
初始化語句;
while(判斷條件語句) { // 條件滿足執行循環體,不滿足退出
循環體語句;
控制條件語句;
}
do { // 先執行循環體,再判斷條件,滿足繼續執行
循環體語句;
控制條件語句;
}while(判斷條件語句);
死循環:
while(true){...}
for(;;){...}
循環控制語句:
break:退出循環
continue:退出本次循環
for(int x=1;x<=10;x++){
if(x%3==0){
//在此處填寫代碼
}
System.out.println("Java基礎班");
}
// 我想在控制檯輸出2次:"Java基礎班" break;
// 我想在控制檯輸出7次:"Java基礎班" continue;
// 我想在控制檯輸出13次:"Java基礎班" System.out.pintln(“Java基礎班”);
注意:System.out.println("*");和System.out.print("*");
的區別
需求:請輸出下列的形狀
// *
// **
// ***
// ****
// *****
class Day04_7 {
public static void main(String[] args) {
for (int i=5;i>0 ;i-- ) {
for (int j=i;j>0 ;j-- ) {
System.out.print("*");
}
System.out.println();
}
}
}
需求:在控制檯輸出九九乘法表。
class JiuJiuBiao
{
public static void main(String[] args)
{
for (int i=1;i<=9 ;i++ )
{
for (int j=1;j<=i ;j++ )
{
System.out.print(j+"x"+i+"="+i*j+' ');
}
System.out.println();
}
System.out.println("by pp");
}
}
轉義字符
寫在字符串中的字符
'\t' tab鍵的位置
'\r' 回車
'\n' 換行
'\"' 轉意字符”
'\'' 轉意字符’
return的作用
- 返回
- 其實它的作用不是結束循環的,而是結束方法的。
return和break以及continue的區別:
- return是結束方法(寫在主方法裏面時候,結束主方法,程序停止運行)
- break是跳出循環
- continue是終止本次循環繼續下次循環
標號:break a;跳到a這個標號處。標號也必須是合法標識符。
方法
提高代碼的複用性,完成特定功能的代碼塊。
方法的格式(寫在主方法外,類中方法外)
修飾符 返回值類型 方法名(參數類型 參數名1,參數類型 參數名2...) {
方法體語句;
return 返回值;
}
- 修飾符:
- 返回值類型:就是功能結果的數據類型。
- 方法名:符合命名規則即可。方便我們的調用。
- 參數:
- 實際參數:就是實際參與運算的。
- 形式參數;就是方法定義上的,用於接收實際參數的。
- 參數類型:就是參數的數據類型
- 參數名:就是變量名
- 方法體語句:就是完成功能的代碼。
- return:結束方法的。
- 返回值:就是功能的結果,由return帶給調用者。
需求:求兩個數據之和的案例
public static int add(int a,int b){
return a+b;
}
注意:
- 方法不調用不執行
- 方法與方法是平級關係,不能嵌套定義
- 方法定義的時候參數之間用逗號隔開
- 方法調用的時候不用再傳遞數據類型
- 如果方法有明確的返回值,一定要有return帶回一個值
方法重載概述和基本使用)
方法重載
在同一個類中,方法名相同,參數列表不同。與返回值類型無關。
參數列表不同:
- 參數個數不同
- 參數類型不同
- 參數的順序不同(算重載,但是在開發中不用)
數組
數組(容器):爲了存儲同種數據類型的多個值
數組是存儲同一種數據類型多個元素的集合。也可以看成是一個容器。數組既可以存儲基本數據類型,也可以存儲引用數據類型。
數組定義格式:
數據類型[] 數組名 = new 數據類型[數組的長度];
數組動態初始化
動態初始化 只指定長度,由系統給出初始化值int[] arr = new int[5];
靜態初始化 給出初始化值,由系統決定長度
- 動態初始化的格式:
數據類型[] 數組名 = new 數據類型[數組長度];
初始化:整數類型:byte,short,int,long都是0;
浮點:float,double都是0.0;
布爾:false
字符:’\u0000’
靜態初始化的格式:(不允許動靜結合,有元素就不寫個數)
- 格式:
數據類型[] 數組名 = new 數據類型[]{元素1,元素2,…};
- 簡化格式:
數據類型[] 數組名 = {元素1,元素2,…};
區別:上一種可以先聲明,再賦值。簡寫形式只能聲明賦值在同一行。
輸出數組名稱和數組元素
打印數組名:[I@19bba45a:前面[代表一維數組([[二維),I代表int類型,後面@符號代表地址值。
注意:兩個異常
- ArrayIndexOutOfBoundsException:數組索引越界異常
- 原因:你訪問了不存在的索引。
- NullPointerException:空指針異常
- 原因:數組已經不在指向堆內存了。而你還用數組名去訪問元素。
- int[] arr = {1,2,3};
- arr = null;
- System.out.println(arr[0]);
數組遍歷
public static void print(int[] arr) {
for (int i = 0;i < arr.length ;i++ ) {
System.out.print(arr[i] + " ");
}
}
eg:求最大值
public static int getMax(int[] arr) {
int max = arr[0];
for (int i = 1;i < arr.length ;i++ ) { //從數組的第二個元素開始遍歷
if (max < arr[i]) { //如果max記錄的值小於的數組中的元素
max = arr[i]; //max記錄住較大的
}
}
return max;
}
二維數組概述
-
二維數組格式:
int[][] arr = new int[3][2];
注意事項:
以下格式也可以表示二維數組
-
1:
數據類型 數組名[][] = new 數據類型[m][n];
-
2:
數據類型[] 數組名[] = new 數據類型[m][n];
-
注意下面定義的區別
int x; int y; int x,y; int[] x; int[] y[]; int[] x,y[]; x是一維數組,y是二維數組
-
{% raw %}
-
二維數組格式:
int[][] arr = new int[3][];
-
二維數組格式:
int[][] arr = {{1,2,3},{4,5},{6,7,8,9}};
{% endraw %}
需求:二維數組遍歷
-
外循環控制的是二維數組的長度,其實就是一維數組的個數。
-
內循環控制的是一維數組的長度。
int[][] arr = {{1,2,3},{4,5},{6,7,8,9}}; for (int i = 0;i < arr.length ;i++ ) { //獲取到每個二維數組中的一維數組 for (int j = 0;j < arr[i].length ;j++ ) { //獲取每個一維數組中的元素 System.out.print(arr[i][j] + " "); } System.out.println(); }
數據類型參數傳遞
基本數據類型傳遞過程不改變原值,因爲調用完會彈棧,局部變量消失。
引用數據類型傳遞改變原值,即使方法彈棧,堆內存數組還在,可以通過地址訪問