如何處理數據

數據的運算

既然是“計算機”,那麼其主要功能就是“計算”了。我們平時使用計算機打遊戲、看電影、聽音樂、上網、處理文檔、科學研究等行爲,本質上都是將各種問題轉換成了計算的問題。
常用的計算包括算術運算、賦值運算、比較運算、邏輯運算、位運算等。表示運算的符號就是運算符。
下面我們來一一學習各種運算和對應的運算符。

算術運算

Java中的算術運算,是以加減乘除爲基礎的一些運算方法。包括:

運算符 說明 示例 結果
+ 正號 i=10; m=+i; m爲10
- 負號 i=10; m=-i; m爲-10
+ 8+4 12
- 8-4 4
* 8*4 32
\ 8\2 4
% 取模(求餘) 9 % 4 1
++ 自增(變量前) i=4;m=++i; i爲5,m爲5
++ 自增(變量後) i=4;m=i++; i爲5,m爲4
自減(變量前) i=4;m=–i; i爲3,m爲3
自減(變量後) i=4;m=i–; i爲3,m爲4

大多數運算都和數學所學相同,不再贅述。着重介紹除法和自增自減運算。

注意:在Java中,實數(float和double類型)是可以進行取模操作的。

除法和求餘

我們先來看一個程序(只顯示主方法內的代碼):

public class Arithmetic01 {
    public static void main(String[] args) {
        System.out.println("8/4="+8/4);//數學計算中結果爲2,結果爲2
        System.out.println("9/4="+9/4);//數學計算中結果爲2.25,結果爲2
        System.out.println("11/4="+11/4);//數學計算中結果爲2.75,結果爲2
        System.out.println("11.0/4="+11.0/4);//數學計算中結果爲2.75,結果爲2.75
        System.out.println("11%4="+11%4);//餘數爲3
        System.out.println("11.5%3.5="+11.5%3.5);//餘數爲1.0
    }
}

運行結果爲:

8/4=2
9/4=2
11/4=2
11.0/4=2.75
11%4=3
11.5%3.2=1.0

通過這個程序,我們可以看到,8除以4結果爲2,這符合我們的預期;但9除以4和11除以4,結果均只有整數部分,這就是整數除法的特點:整數除以整數,結果還是整數
如果我們希望得到期望中的小數,將除法運算中任何一個數改爲實數類型即可。
這個特性是由計算機中整數的存儲和處理方法決定的,因此我們在使用除法時一定要特別注意。
此外,在Java中,實數(float和double類型)是可以進行取模操作的。

自增和自減

自增、自減,顧名思義,就是爲使用這個運算的變量自身增加1或者減少1。例如變量x原來的值是40,使用自增運算後,x的值爲41;如果變量x原來的值是40,使用自減運算後,x的值爲39。讓上面的表中,最令人迷惑的就是:當自增|自減運算是其它運算的一部分時,變量和自增|自減運算的位置不同,會導致最終結果的不同。由於自增和自減的規則相同,所以下面這個例子中只使用了自增運算:

public class Arithmetic02 {
    public static void main(String[] args) {
        int x = 10;
        int y;
        System.out.println("x=" + x);//x的初始值爲10
        x++;
        System.out.println("進行x++運算後,x=" + x);//自增運算一次,x值爲11
        ++x;
        System.out.println("進行++x運算後,x=" + x);//再自增運算一次,x值爲12
        //先提取x的值進行賦值運算,再進行自增運算
        System.out.println("x+++y=" + (x+++y)+",x="+x+",y="+y);
        //先進行自增運算,再提取x的值進行賦值運算
        System.out.println("++x+y=" + (++x+y)+",x="+x+",y="+y);

    }
}

運行結果是:

x=10,y=20
進行x++運算後,x=11
進行++x運算後,x=12
x+++y=32,x=13,y=20
++x+y=34,x=14,y=20

通過這個例子,不難總結:如果自增|自減運算是單獨進行的,那麼變量和運算符的位置關係不影響最終結果;如果自增|自減運算是其它運算中的一部分,那麼變量在前面時,就先把變量的值代入到整個運算中,運算完畢後再進行自增|自減運算,運算符在前面時,就先進行自增|自減運算,然後把結果代入到整個運算中。

賦值運算

賦值運算我們一直在用,前面的程序中:int x=10;。這可不能讀作“整型變量x等於10”,而是“把10賦給整型變量x”。這個=在數學上是“等號”,但在Java中是“賦值運算符”,它的作用是把運算符右邊的賦給左邊的變量。所以:

  • 賦值運算是從右向左進行的。a=a+1這樣的代碼在執行時,就會先把右邊的變量a的值提取出來,加1,再將和存入到變量a中。同時,代碼int a,b,c;a=b=c=10;是正確的,因爲從右向左賦值;但int a=b=c=10;是錯誤的,因爲10先賦給了c,但c還沒有定義。
  • 右邊必須是一個確定的值或能求出確定值的運算式,左邊則必須、只能是個變量

爲了簡化代碼,還有以下賦值運算符:

運算符 說明 示例 相當於
+= 加等於 a+=3 a=a+3
-= 減等於 a-=3 a=a-3
*= 乘等於 a*=3 a=a*3
\= 除等於 a\=3 a=a\3
%= 模等於 a%=3 a=a

02

 

比較運算

在Java中可以對兩個數值進行大小比較,其結果爲一個布爾值,true表示比較成立,false表示不成立。比較運算包括:

運算符 說明 示例 結果
== 等於 50==23 false
!= 不等於 50!=23 true
> 大於 50>23 true
< 小於 50<23 true
>= 大於等於 50>=23 true
<= 小於等於 50<=23 true

大家可以編寫並運行以下程序(只顯示主要部分):

public class Compare {
    public static void main(String[] args) {
        System.out.println("50==23?"+(50==23));
        System.out.println("50!=23?"+(50!=23));
        System.out.println("50>23?"+(50>23));
        System.out.println("50<23?"+(50<23));
        System.out.println("50>=23?"+(50>=23));
        System.out.println("50<=23?"+(50<=23));
    }
}

結果爲:

50==23?false
50!=23?true
50>23?true
50<23?false
50>=23?true
50<=23?false

邏輯運算

邏輯運算是針對邏輯值(布爾類型)的運算,其結果還是一個布爾類型的值。邏輯運算包括:

運算符 說明 示例 結果
&和&& a&b(a&&b) 當a和b均爲true時,結果爲true,其他情況均爲false
| 和 || a|b(a||b) 當a和b均爲false時,結果爲false,其他情況均爲true
! !a 取相反值,a爲true時,!a爲false;a爲false時,!a爲true
^ 異或 a^b a、b值相同時爲false,不相同時爲true

與和或運算均出現了兩個符號。其中,&和|中包含其它運算時,所有的運算都會被執行;&&和||中包含其它運算時,如果在不完成所有運算的情況下就能得出結論,那麼不再執行剩下的運算。
由於短路與和短路或情況類似,我們這裏只看短路或的例子。對於短路與,大家可以編寫下面的程序:


public class LogicDemo {
    public static void main(String[] args) {
        int a=100;
        int b=200;
        boolean c=true;
        boolean d=false;
        System.out.println("邏輯或:"+(c|d));
        System.out.println("邏輯與:"+(c&d));
        System.out.println("邏輯異或:"+(c^d));
        System.out.println("邏輯非:"+(!c));
        System.out.println("使用普通或運算:");
        System.out.println((a>20)|(++b>500));//a>20值爲true,++b>500值爲false,同時b自增1,結果爲true
        System.out.println("b="+b);//輸出b的值,爲201
        System.out.println("使用短路或運算:");
        System.out.println("計算(a>20)||(++b>500):"+((a>20)||(++b>500)));//a>20值爲true,此時已經可以確定最終結果,++b>500沒有執行
        System.out.println("b="+b);//輸出b的值,爲201
        System.out.println("計算(a<20)||(++b>500):"+((a<20)||(++b>500)));//a<20值爲false,此時不能確定最終結果,++b>500需要執行
        System.out.println("b="+b);//輸出b的值,爲202
    }
}

運行結果爲:

邏輯或:true
邏輯與:false
邏輯異或:true
邏輯非:false
使用普通或運算:
true
b=201
使用短路或運算:
計算(a>20)||(++b>500):true
b=201
計算(a<20)||(++b>500):false
b=202

其它運算大家可以自己寫程序進行驗證和練習。

位運算

位運算只能用於整型數據,而且只能在二進制層面進行運算。整型數據在計算機中是以二進制形式存儲,位運算也是針對二進制數據進行的運算。主要包括:

運算符 說明 示例 結果
& 按位與 a&b 參與運算的兩位都是1,結果爲1,其餘爲0
| 按位或 a|b 參與運算的兩位都是0,結果爲0,其餘爲1
~ 取反 ~a 1變爲0,0變爲1
^ 異或 a^b 參與運算的兩位相同爲0,不同爲1
<< 左移 a<<2 二進制數據向左移動2位,右端補0
>> 右移 a>>2 二進制數據向右移動2位,正數左端補0,負數補1
>>> 無符號右移 a>>>2 二進制數據向右移動2位,無論正負均補0

在與、或、異或的位運算中,參與運算的兩個數必須是二進制形式,右對齊,左邊不足補0,從右向左進行計算。例如:

  10011001
& 00001101
----------
  00001001

取反時,將二進制的1轉換爲0,0轉換爲1。需要注意的是,由於正整數和負整數在內存中的表示方法不同,對十進制的整數1進行取反操作,結果是-2,而不是0。
左移時,將最左邊的數據移出變量的存儲空間,右側補0。如果左移時,沒有1被移出存儲空間,每左移一位,就相當於乘以一次2。
右移時,將最右邊的數據移出變量的存儲空間,但由於最左邊那一位是符號位,左邊補0還是1,產生兩種處理方式:一是正數補0,負數補1,即>>;二是無論正負,一律補0,即>>>
大家可以編寫並運行以下程序,思考一下具體執行過程:

public class BitOperate {
    public static void main(String[] args) {
        int a=1;//二進制形式爲01,省略了前面30字位的0
        int b=3;//二進制形式爲11,省略了前面30字位的0
        System.out.println("a&b="+(a&b));//01&11=01,十進制的1
        System.out.println("a|b="+(a|b));//01|11=11,十進制的3
        System.out.println("a^b="+(a^b));//01^11=10,十進制的2
        System.out.println("~a="+(~a));//~01=10,前面30字位的0也要取反爲1,所以實際答案是11111111111111111111111111111110,-2
        System.out.println("a<<2="+(a<<2));//a左移兩位,爲4
        System.out.println("-a<<2="+((-a)<<2));//-a,即-1左移兩位,爲-4
        System.out.println("b>>1="+(b>>1));//b右移1位,爲1
        System.out.println("-b>>1="+((-b)>>1));//-b右移1位,爲-2
        System.out.println("b>>>1="+(b>>>1));//b無符號右移1位,爲1
        System.out.println("-b>>>1="+((-b)>>>1));//-b無符號右移1位,爲2147483646
    }
}

條件運算

Java中還有一個條件運算,也是Java唯一一個三目運算符(這個運算涉及到三個參數)。它的格式是:表達式1?表達式2:表達式3
表達式1必須是邏輯表達式——其自身或者運算結果必須是個邏輯值,true或者false。如果表達式1的值是true,整個運算的結果就是表達式2的值;如果表達式1的值是false,整個運算的結果就是表達式3的值。也就是說,條件運算可以根據條件的不同(表達式1的值),來產生不同的結果(表達式2和表達式3的值)。
我們來看這個程序:

public class SelectiveOperation {
    public static void main(String[] args) {
        int a=300;
        int b=500;
        byte score=90;
        System.out.println("a和b中:"+(a>b?"a比較大":"b比較大"));
        System.out.println("你的考試成績:"+(score>=60?"及格":"不及格"));
    }
}

02

 

數據類型轉換

之前我們提到,9/4=2,這是由於計算機中不同數據類型的保存和處理方法是不同的。這就帶來一個問題,當不同類型的數據放到一起進行運算時,該如何處理?
答案是通過數據類型轉換,把不同類型的數據轉換爲相同的數據類型,再進行運算。
具體轉換方法這裏不進行深入探討,我們主要學習在什麼情況下使用哪種轉換方式。
在Java中,有兩種數據類型轉換方式:自動類型轉換和強制類型轉換。

自動類型轉換

顧名思義,不需要我們手工干預就可以完成。一般來說,當兩個不同類型的數據在一起運算時,表示範圍小、精度低的數據類型會轉換爲表示範圍大、精度高的類型。
轉換規律爲:
(byte,short,char)–>int–>long–>float–>double
byte,short和char三種類型都會轉換爲int類型——即使運算中不包含int類型時也是如此,例如兩個short類型數據在一起運算。

強制類型轉換

我們有時需要手工指定轉換目標,例如把表示範圍大、精度高的類型轉換爲範圍小、精度低的類型。轉換方法:(目標數據類型)轉換對象,例如:(int)3.14;這會把3.14(double類型)強制轉換爲int類型,結果爲3。
不過有時也需要強制把表示範圍小、精度低的類型會轉換爲表示範圍大、精度高的類型,例如在計算平均分時,我們需要用總分除以人數。人數必然是整數,分數很多時候也是分數,很容易在無意間寫成兩個整數相除,結果必然還是整數。我們可以把計算平均分的方法寫成:

//avg方法用於計算平均分,sum表示總分,num表示人數
double avg(int sum,int num){
    return (double)sum/num;
}

在這個方法中,sum會被強制轉換爲double類型,那麼結果自然也是double類型了。

需要注意的是:除了=之外的所有賦值運算符,都會在需要時自動進行強制類型轉換。如:

    short s=50;
    int i=100;
    s+=i;

我們看這個對類型轉換進行總結的程序:

public class DTConversion {
    public static void main(String[] args) {
        //整數的自動類型轉換
        byte b=34;
        short s=23;
        s=(short)(s+b);//自動轉換時,short數據和byte數據相加,會轉換爲int數據,所以不能直接賦值給short變量
        System.out.println("自動進行強制轉換:"+(s+=b));//這種形式的賦值運算會自動進行強制轉換
        System.out.println("不轉換:"+(12/5));
        System.out.println("自動類型轉換:"+(12.0/5));
        System.out.println("強制類型轉換:"+((double)12/5));
        System.out.println("強制轉換可能會導致精度損失:"+(int)12.5);
    }
}

運算符的優先級

Java中包含了很多運算符,當這些運算符在同一個運算式中時,必須規定執行順序,這就是優先級。Java中運算符的優先級是這樣規定的:

優先級 運算符 結合性
1 .、()、[]、{} 從左向右
2 !、+、-、~、++、– 從右向左
3 *、/、% 從左向右
4 +、-(正負號) 從左向右
5 <<、 >>、 >>> 從左向右
6 <、 <=、 >、>=、instanceof 從左向右
7 ==、!= 從左向右
8 & 從左向右
9 ^ 從左向右
10 | 從左向右
11 && 從左向右
12 || 從左向右
13 ?: 從右向左
14 =、+=、-=、*=、/=、%=、<<=、>>=、>>>=、&=、~=、^=、|= 從右向左

由於小括號的優先級非常高,因此,如果暫時記不住這個表,那麼可以用小括號把需要先計算的部分括起來。但仍需要通過記憶和練習,記住他們的優先級的。

02

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章