Java的數(shù)據(jù)類型
$$
2 + 5
$$
Java是一門純粹的面向?qū)ο缶幊陶Z言搏色,除了8個基本數(shù)據(jù)類型不是對象以外涩僻,其他的一切的都是對象晌涕。那么問題來了,這8個數(shù)據(jù)類型分別是啥撞鹉?
不難發(fā)現(xiàn)疟丙,Java的數(shù)據(jù)類型和C語言基本上都是一致的颖侄,兩者都不包含字符串這種數(shù)據(jù)類型。盡管Java可以使用String str=Hello World!"
這種方法來定義字符串享郊,但其實和char str[] = "Hello World!"
本質(zhì)是一樣的览祖,也就是通過組合字符數(shù)據(jù)類型和數(shù)組來保存字符串。因此就對單引號和雙引號進行了區(qū)分炊琉,而在Python里面沒有單個字符展蒂,只有長度為1的字符串。
這幾種基本數(shù)據(jù)類型可以相互轉(zhuǎn)換苔咪,分為強制轉(zhuǎn)換和自動轉(zhuǎn)換兩種類型锰悼,如下代碼
//強制轉(zhuǎn)換
int a = (int) (3.14 * 2.13)
// a =6
// 自動轉(zhuǎn)換
float b = a
// b = 6.0
除了基本數(shù)據(jù)類型外,Java還有一種稱之為引用類型团赏,包括類箕般、接口和數(shù)組類型以及特殊的null類型。所謂引用類型就是對一個對象的引用舔清,聽起來好像是C語言的指針一樣丝里,其實就是,只不過Java不再使用指針這個說法鸠踪。
Java的運算符
Java的運算符有如下幾種
- 算術(shù)運算符: +, -, *, , %
- 賦值運算符: =, +=, -= ...
- 比較運算符: >, >=, <, <=, ==
- 邏輯運算符: &&, ||, !
- 位運算符: &, |, ~, ^, <<, >>, >>>. 從來沒有用過丙者,我很尷尬,只知道效率很高营密。
- 三目運算符:(expression) ? 條件為真時 : 條件不為真時
通過將運算符和數(shù)據(jù)結(jié)合就構(gòu)成了賦值表達式,而當(dāng)使用多個類型的運算符時需要注意運算符之間的優(yōu)先級關(guān)系目锭。不過真實的編程世界不會存在多個運算符同時登場讓你懷疑人生评汰,以為自己在參加什么證書考試。如果有哪個程序員閑的蛋疼真的要這樣做痢虹,直接開除好了被去,否則留著心累嗎。
將運算符和不同數(shù)據(jù)類型進行結(jié)合就是運算表達式奖唯,運行結(jié)果不會直接丟掉惨缆,而是保存在變量中。
Java的變量
編程的本質(zhì)可以認為就是對內(nèi)存中的數(shù)據(jù)的訪問和修改丰捷。計算機在內(nèi)存中開辟空間用于存放數(shù)據(jù)坯墨,那么程序如何訪問這些數(shù)據(jù)并進行修改呢?盡管每個數(shù)據(jù)在內(nèi)存上都有一個確定的位置病往,但是程序員肯定是不會通過手動輸入地址的方式來獲取數(shù)據(jù)捣染,而是為存放在內(nèi)存中的數(shù)據(jù)賦予一個變量名,通過訪問變量名的方式來對數(shù)據(jù)做一系列的修改停巷。
Java和C都是強類型的編程語言耍攘,強類型有兩種特征:1. 所有的變量都必須先聲明后才能使用榕栏;2. 指定類型的變量只能接受類型與之匹配的值。也就是說下面這段Python代碼在Java編譯時會出錯蕾各。
c = 1
c = 'abc'
在Java和C這種強類型語言中扒磁,你需要這樣寫:
int num = 1
char str[] = "abc"
強類型有一定的優(yōu)點,能夠提高運行速度式曲,降低一些編碼錯誤渗磅。對于我這種沒有好好深入學(xué)習(xí)強類型語言的人而言,目前還在思索如何讀取不定行數(shù)字符串輸出成一個检访。不難發(fā)現(xiàn)Java中的變量定義由3部分組成:基本數(shù)據(jù)類型 + 變量名(聲明符) + 變量值(可選)始鱼。當(dāng)然后面指針的定義會稍微復(fù)雜。
Java的三種程序結(jié)構(gòu)
1996年脆贵,計算機科學(xué)家Bohm和Jacopini證明了“無論一個算法是否簡單医清,還是足夠復(fù)雜,都可以用順序結(jié)構(gòu)卖氨,選擇結(jié)構(gòu)和循環(huán)結(jié)構(gòu)這三種基本結(jié)構(gòu)組合而成”会烙。因此所有計算機編程語言都會具備這三個基本結(jié)構(gòu),以我淺顯碼代碼生涯筒捺,還沒有遇到一門語言不存在這三個基本組合柏腻。
順序結(jié)構(gòu):順序結(jié)構(gòu)就是從上到下運行,行云流水系吭,沒有猶豫(條件語句)五嫂,沒有彷徨(循環(huán)語句),一直到程序運行結(jié)束為止肯尺。之前的HelloWorld禱告與就是如此沃缘。非常直白,不需要多余的解釋则吟。
分支結(jié)構(gòu):Java提供了兩種常見的分支控制結(jié)構(gòu):if語句和switch語句槐臀。Python之父覺得switch沒啥必要,所以Python里只有if-else氓仲。
循環(huán)結(jié)構(gòu):循環(huán)有三種水慨,while, do while,for. 并且循環(huán)可以套循環(huán)。談及循環(huán)結(jié)構(gòu)就一定要說說break
和continue
兩者的區(qū)別敬扛,前者是徹底不干晰洒,后者是當(dāng)前循環(huán)內(nèi)容不做,繼續(xù)搞下一個循環(huán)舔哪。
數(shù)據(jù)結(jié)構(gòu):數(shù)組
基本數(shù)據(jù)類型的元素在內(nèi)存中隨機存放欢顷,數(shù)組是一種最常見的數(shù)據(jù)結(jié)構(gòu),用于將相同類型的數(shù)據(jù)存放在同一塊內(nèi)存區(qū)捉蚤。在C/C++里面抬驴,數(shù)組一般都要和指針聯(lián)系在一起炼七。Java沒有說指針這個概念,提出了引用類型布持。
數(shù)組定義
Java支持兩種方式定義數(shù)組:
type[] arrayName;
type arrayName[];
我看的書里面推薦Java里使用數(shù)組時建議以第一種格式進行豌拙。因為第一種有著更好的可讀性,一看就知道int和int[]是兩種不同的數(shù)據(jù)類型题暖,int是基本類型按傅,而int[]就是引用類型。但是在C/C++里面胧卤,似乎只能用第二種格式唯绍。為什么不能用第一種格式呢?當(dāng)我看到int *(&arry)[10] = ptrs
枝誊,我覺得這就是一個原因吧况芒。
還有Java定義數(shù)組不能指定數(shù)組的長度。因為定義數(shù)組只是定義了一個引用變量叶撒,并未指向任何有效的內(nèi)存空間绝骚,也就是說沒有內(nèi)存空間來存儲數(shù)組元素。只有當(dāng)數(shù)組進行初始化后才能使用這個數(shù)組祠够。
數(shù)組初始化
數(shù)組初始化意味著在內(nèi)存中開辟一個空間压汪,這個空間存放數(shù)組元素,每個數(shù)組元素都需要被賦值古瓤。這個值可以手動指定止剖,也可以系統(tǒng)自動賦予,或者就是null數(shù)據(jù)類型湿滓。Java初始化數(shù)組由兩種方式:靜態(tài)初始化和動態(tài)初始化滴须。
- 靜態(tài)初始化:程序員顯式指定每個數(shù)組元素的初始值,系統(tǒng)決定數(shù)組長度
- 動態(tài)初始化: 程序員顯式指定數(shù)組長度叽奥,系統(tǒng)分配初始值
首先是靜態(tài)是初始化的定義方法:
//方法1
int[] intArr //定義好一個int數(shù)組類型的變量,也就是引用變量
intArr = new int[] {5,6,7,8} // 將這個引用變量指向一個int數(shù)組
// 方法2痛侍,兩步一起來
int[] intArr = {5,6,7,8}
動態(tài)初始化方法
// 方法1
int[] prices
price = new int[5]
// 方法2
price = new int[5]
數(shù)組使用
數(shù)組的常見用法就是訪問數(shù)組元素朝氓,包括對數(shù)組元素進行賦值和取出數(shù)組元素的值≈鹘欤可以單獨訪問一個元素赵哲,也可以通過for循環(huán)和foreach循環(huán)的方式對數(shù)組進行遍歷。當(dāng)然foreach
是Java5之后出現(xiàn)的特性君丁,舉個例子
public class forEachTest
{
public static void main(String[] args)
{
int[] prices;
prices = new int[5];
for (int i =0; i < prices.length; ++i)
{
prices[i] = i;
}
//price是形參枫夺,prices則是數(shù)組名
for (int price : prices)
{
System.out.println(price);
}
}
}
注:foreach只能用于遍歷數(shù)組,而不能對數(shù)組賦值绘闷。
數(shù)組的一些機制
為了更好理解的數(shù)組橡庞,你需要知道兩個新的概念:堆(heap)和棧(stack)较坛。
棧(stack)又名堆棧,它是一種運算受限的線性表扒最。其限制是僅允許在表的一端進行插入和刪除運算丑勤。這一端被稱為棧頂,相對地吧趣,把另一端稱為棧底法竞。向一個棧插入新元素又稱作進棧、入椙看欤或壓棧岔霸,它是把新元素放到棧頂元素的上面,使之成為新的棧頂元素俯渤;從一個棧刪除元素又稱作出棿粝福或退棧,它是把棧頂元素刪除掉稠诲,使其相鄰的元素成為新的棧頂元素侦鹏。
堆(heap):是計算機科學(xué)中一類特殊的數(shù)據(jù)結(jié)構(gòu)的統(tǒng)稱。堆通常是一個可以被看做一棵樹的數(shù)組對象臀叙。
我覺得你肯定會一臉懵逼的略水,所以看下圖直觀感受下數(shù)組在內(nèi)存的存放形式。
數(shù)組分為數(shù)組引用變量和數(shù)組的實際對象劝萤,這兩個存放在不同的位置渊涝。編程時通過數(shù)組引用變量對實際的數(shù)組對象進行修改。
基本數(shù)據(jù)類型的數(shù)組定義床嫌,初始化和數(shù)組操作的代碼和內(nèi)存中的變化如下
public class BasicArrayTest
{
public static void main(String[] args)
{
int[] numArry;
numArry = new int[8]
for (int i = 0; i < numArry.length; ++i)
{
numArry[i] = i + 1;
System.out.println(numArry[i]);
}
}
}
數(shù)組的拓展和用途
Java8增加一個工具類Arrays用于處理數(shù)組跨释,可以在https://docs.oracle.com/javase/8/docs/api/index.html學(xué)習(xí)用法。
數(shù)組的用途也很廣厌处,比如說你可以編一個命令行圍棋工具,但是目前的用途就是做題目鳖谈。在知乎上有一個提問是一行Python能實現(xiàn)什么喪性病狂的功能,幾個小例子告訴你, 一行Python代碼能干哪些事. 我們要根據(jù)本次學(xué)習(xí)的Java基本語法實現(xiàn)
- 輸出特定字符"Love"拼成的心形
- 輸出Mandelbrot圖像
- 打印九九乘法表
- 輸出斐波那契數(shù)列
讓我們用Java代碼根據(jù)Mandelbrot的定義利用數(shù)組生成一副Mandelbrot圖.先說一件很尷尬的事情阔涉,Java的基本數(shù)據(jù)類型里面沒有復(fù)數(shù)缆娃,且我學(xué)Java時間合起來也不到3天,所以我就通過搜索引擎找到了一個復(fù)數(shù)類湊合用瑰排。代碼如下贯要,比起代碼更重要的是對數(shù)學(xué)公式的理解。
public class Mandelbrot
{
public static void main(String[] args)
{
// define the iteration
int maxIterations = 100;
// define the position range
int xstart = -80;
int xend = 40;
int ystart = -40;
int yend = 40;
// define the scale
double scalingFactor = 1.0 / 40;
//define the two dimension array
char[][] mandelbrot = new char[xend - xstart][yend-ystart];
for (int x = xstart; x < xend; ++x)
{
for (int y = ystart; y < yend; ++y)
{
// whether the mod in the iteration will be large than 2
Complex current = new Complex(x * scalingFactor, y * scalingFactor);
Complex temp = current;
for (int iter = 0; iter < maxIterations; ++iter)
{
temp = temp.times(temp).plus(current);
if (temp.mod() > 2){
mandelbrot[x-xstart][y-ystart] = ' ';
break;
}else
{
mandelbrot[x-xstart][y-ystart] = '*';
}
}
}
}
// output the result
for (int y = ystart; y < yend; ++y)
{
for (int x = xstart; x < xend; ++x)
{
System.out.print(mandelbrot[x-xstart][y-ystart]);
}
System.out.print('\n');
}
}
}
結(jié)果咋那么丑呢椭住。崇渗。
參考資料: