二.Java基本语法
转载自:
【标识符】:
Java 对各种变量、方法和类等要素命名时使用的字符序列称为标识符。
凡是自己可以起名字的地方都叫标识符
命名规则:(一定要遵守,不遵守就会报编译的错误)
由26个英文字母大小写,0-9 ,_或 $ 组成
数字不可以开头。
不可以使用关键字和保留字,但能包含关键字和保留字。
Java中严格区分大小写,长度无限制。
标识符不能包含空格。
注意:在起名字时,为了提高阅读性,要尽量有意义,“见名知意”。
Java中的名称命名规范:(不遵守,也不会出现编译的错误)
包名:多单词组成时所有字母都小写:xxxyyyzzz
类名、接口名:多单词组成时,所有单词的首字母大写:XxxYyyZzz
变量名、方法名:多单词组成时,第一个单词首字母小写,第二个单词开始每个单词首字母大写:xxxYyyZzz
常量名:所有字母都大写。多单词时每个单词用下划线连接:XXX_YYY_ZZZ
【关键字】:
被Java语言赋予了特殊含义,用做专门用途的字符串(单词),关键字中所有字母都为小写。
用于定义数据类型的关键字:
class interface enum byte short int long float double char boolean void
用于定义数据类型值的关键字:true false null
用于定义流程控制的关键字:
If else switch case default while do for break continue return
用于定义访问权限修饰符的关键字:private protected public
用于定义类,函数,变量修饰符的关键字:abstract final static synchronized
用于定义类与类之间关系的关键字:extends implements
用于定义建立实例及引用实例,判断实例的关键字:new this super instanceof
用于异常处理的关键字:try catch finally throw throws
用于包的关键字:package import
其他修饰符关键字:native strictfp transient volatile assert
保留字:
Java版本尚未使用,但以后版本可能会作为关键字使用。
自己命名标记符时要避免使用这些保留字:
byValue、cast、future、 generic、 inner、 operator、 outer、 rest、 var 、 goto 、const
l 变量的概念:
- 内存中的一个存储区域
- 该区域有自己的名称(变量名)和类型(数据类型)和值
- Java中每个变量必须先声明,再赋值,然后才能使用
- 该区域的数据可以在同一类型范围内不断变化
- Java 中的变量有四个基本属性:变量名,数据类型,存储单元和变量值
变量名:合法的标识符
变量的数据类型:可以是基本类型和引用类型(必须包含类型)
存储单元:存储单元大小是由数据类型决定的,如:int 为4 个字节32 位
变量值:在存储单元中放的就是变量值(如果是基本类型放的就是具体值,如果是引用类型放的是内存地址,如果null,表示不指向任何对象)
l 定义变量的格式:数据类型 变量名 = 初始化值
l 变量是通过使用变量名来访问这块区域的
//int是一种数据类型,是整型。
int a; //在内存中开辟一块空间,这块空间的类型是整型,给这块空间起名叫a
//赋值
a = 100;
//通过变量名去访问那块内存。
System.out.println(a);
//重复访问
System.out.println(a);
l 使用变量注意:
- 变量的作用域:一对{ }之间有效。出了大括号就不认识了。
- 初始化值
- 变量可以重复赋值,但不能重复声明,在同一个域中,变量名不能重复。
2.1 关于java中的字面值:
>引用类型默认值:null
>8种基本数据类型:注意定义值时不能超过范围
整型:byte(8 bit) short int(默认类型)long:变量值的末尾要加“L”或“l”
eg:byte = 1,存储在计算机上为 0000 0001。
浮点型:float:末尾要加上“F”或“f”、 double (默认类型)
字符型:char(用‘ ’括起来)只能表示一个字符(英文/中文/标点/转义字符等),默认值是“\u0000”,要定义多个字符用string。
布尔类型: boolean(只能取值为true 或false,不能取null),默认值是false。
2.3 java中变量按照声明位置的不同来分类:
2.4.1二进制:计算机底层都是用二进制来存储、运算。
2.4.2二进制与十进制之间的转换。
二进制转换为十进制:从右向左,2^0 + 2^1 +···+2^n
十进制转换为二进制:
2.4.3二进制在底层存储:正数、负数都是以补码的形式存储的。(原码、反码、补码)
正数:原码、反码、补码三码合一
负数:正数的原码符号位由0变1è负数的原码è负数原码除符号位按位取反è负数的反码è负数反码加1è负数的补码
2.4.4四种进制间的转换
2.5变量的运算:不考虑布尔Boolean类型
正号: + 负号: -
加号: + 减号: - 乘号: * 除号: / 取模: %
前/后置加: ++ 前/后置减 –
连接符: +
注意:1)除:/
int i = 12;
int j = i/5;
double d = i / 5;
double d1 = i/5.0;
System.out.println(j);//2
System.out.println(d);//2.0
System.out.println(d1);//2.4
2)取模:%:取余数. 结果的符号取决于被模数(%左边的数)
int i1 = 12 % 5;
int i2 = -12 % 5;
int i3 = 12 % (-5);
int i4 = -12 % (-5);
System.out.println(i1);//2
System.out.println(i2);//-2
System.out.println(i3);//2
System.out.println(i4);//-2
3)前++:先自增1,后做运算;后++:先做运算,后自增1
--------------------------------------------------------------------------
int myInt1 = 10;
int myInt2 = myInt1++;//后++
System.out.println(myInt1);//11
System.out.println(myInt2);//10
------------------------------------------------------------------------
int myInt3 = 10;
int myInt4 = ++myInt3;//前++
System.out.println(myInt3);//11
System.out.println(myInt4);//11
-----------------------------------------------------------------------------
4)连接符 +:String字符串与其他数据类型只能做连接运算,且结果为String类型。
“+”除字符串相加功能外,还能把非字符串转换成字符串。
【举例】:
class Testjia
public static void main(String[] args)
{
System.out.println("5+5="+5+5); //输出:5+5=55
System.out.println('*' + '\t' +'*');//输出:93
System.out.println("*" + '\t' +'*');//输出:* *
}
3.2赋值运算符:
== !=
> < > = <=
instanceof 检查是否是类的对象
【举例】
|
范例 |
结果 |
|
“Hello” instanceof String |
true |
|
“Hello” instanceof System |
false |
【注意】
① 区分 == 与 = 区别。
② 进行比较运算操作以后,返回一个boolean类型的值,要么是true,要么是false。
4 >= 3 表达的是4 > 3或者 4 = 3。结果是true。
③if(i > 1 && i < 10){ } 不能写为:if(1 < i < 10){ }
3.4逻辑运算符(运算符的两端是boolean值)
位运算是直接对二进制进行运算,注意:无<<<(无符号左移)
|
运算符 |
运算 |
范例 |
|
<< |
左移 |
3 << 2 = 12 --> 3*2*2=12 ;m< |
|
>> |
右移 |
3 >> 1 = 1--> 3/2=1 ;m>>n结果:m/(2^n) |
|
>>> |
无符号右移 |
3 >>> 1 = 1 --> 3/2=1;m>>>n结果:m/(2^n) |
|
& |
与运算 |
6 & 3 = 2 |
|
| |
或运算 |
6 | 3 = 7 |
|
^ |
异或运算 |
6 ^ 3 = 5 |
|
~ |
反码 |
~6 = -7 |
【规则】
① 左移(二进制左移n位,低位补0)有限度,正数的二进制左移后,首位变1了就错了
② 右移:二进制右移n位,原来最高位是几,高位就补几
③ 无符号右移:二进制右移n位,无论高位是几,高位都补0
④ 与运算:左右两端数的二进制所对应位都是1则变1,否则为0,所得二进制数为结果
⑤ 或运算:左右两端数的二进制所对应位至少有一个是1则变1,否则为0,所得二进制数为结果
⑥ 异或运算:左右两端数的二进制所对应位不同则变1,否则为0,所得二进制数为结果
⑦ 反码:该数的二进制对应位1变0,0变1,最后所得二进制数为结果
【小练习】
交换两个变量的值
//方法一:提供一个临时变量。
Int temp = m;
m = n;
n = temp;
System.out.println("m:" + m + " n:" + n);
//方法二:当m和n较大时,有可能出现精度损失
m = m + n;//m = 12 + 5;
n = m - n;//n = 17 - 5;
m = m - n;//m = 17- 12
System.out.println("m:" + m + " n:" + n);
//方法三:优点:没有上面两种方法的缺点。缺点:难!
m = m ^ n;
n = m ^ n; //(m ^ n) ^ n == m
m = m ^ n; //(m ^ n) ^ m == n
System.out.println("m:" + m + " n:" + n);
3.6三元运算符
●运算符有不同的优先级,所谓优先级就是表达式运算中的运算顺序。如下表,上一行运算符总优先于下一行;只有单目运算符、三元运算符、赋值运算符是从右向左运算的。
【小练习】输出60的十六进制。
int i = 60;
//法一:自动调用Integer类现成的方法
String binary = Integer.toBinaryString(i);System.out.println(binary);
String hex = Integer.toHexString(i);System.out.println(hex);
//法二:手动的方式,从控制台输出60的十六进制。
/*
char c = 'a';
char c1 = (char)(c + 2);
System.out.println(c1);//c
*/
int j = i & 15;//获取到i的最低4位对应的值。
String k1 = (j <= 9)? j + "" : (char)(j - 10 + 'a') + "";
i = i >> 4;
int z = i & 15;
String k2 = (z <= 9)? z + "" : (char)(z - 10 + 'a') + "";
System.out.println(k2 + k1);
4.1关于代码的三种结构
4.2.1条件判断: if-else语句
格式:
|
switch(变量){ case 常量1:语句1;break; case 常量2:语句2;break; … … case 常量N:语句N;break; default:语句;break; |
规则:
①switch(表达式)中表达式的返回值必须是下述几种类型之一:byte,short,char,int,枚举,String;
②case子句中的值必须是常量,且所有case子句中的值应是不同的;
③default是可以省略的,并且其位置也是灵活的,但是通常将其放在case语句之后,当没有匹配的case时,执行default;
④break语句用来在执行完一个case分支后使程序跳出switch语句块;break语句也可以没有,如果没有break,程序会顺序执行到switch结尾。
switch和if语句的对比:
⑤如果判断的具体数值不多,而且符合byte、 short 、int、 char这四种类型。虽然两个语句都可以使用,建议使用swtich语句。因为效率稍高。
⑥其他情况:对区间判断,对结果为boolean类型判断,使用if,if的使用范围更广。
4.3循环结构
|
for(表达式1;表达式2;表达式3){ java语句; } |
表达式1是初始化表达式,最先执行,只执行一次。表达式2必须是boolean类型的表达式。
for循环开始执行,先执行表达式1,并只执行一次。进而判断表达式2的结果,如果是true,则执行java语句。再执行表达式3,然后再判断表达式2的结果,直到表达式2的结果是false,则for循环结束。
注:①死循环
|
for(;;){ System.out.println("Test"); } |
doc环境下按ctrl+c 停止,强制退出。
②关于for循环的嵌套,所有控制语句都可以嵌套在一起使用。
|
public class ForTest02{ public static void main(String[] args){ for(int i=5;i>0;i--){ for(int j=0;j System.out.print(j+" "); } //换行 //System.out.println(); System.out.print("\n"); } } |
练习:①使用嵌套的for循环打印九九乘法表
1*1=1
2*1=2 2*2=4
.......
9*1=9...............9*9=81
|
public class ForTest03{ public static void main(String[] args){ for(int i=1;i<=9;i++){//一共有9行 for(int j=1;j<=i;j++){//每行有i个等式 System.out.print(i + "*"+ j +"=" + (i*j) + " "); } System.out.println(); } }} |
②计算1-100之间所有奇数的求和。
|
public class ForTest04{ public static void main(String[] args){ /* int sum = 0; for(int i=1;i<=100;i++){ if(i%2 != 0){ //奇数 //追加 sum += i; } } System.out.println(sum); */ //加入人为因素 //效率高. int sum = 0; for(int i=1;i<=99;i+=2){ sum += i; } System.out.println(sum); } |
4.3.2 while 循环语句(while循环的次数是:0-N次)
|
do{ java语句; }while(boolean表达式); |
注:①不同的循环结构之间可以相互转换
②while和do-while的区别:do-while程序至少会执行一次。while先判断符合条件才执行,do-while循环先执行一次再判断。
③死循环:
|
while(true){ System.out.println("Test"); } |
④嵌套循环:循环结构还可以声明循环。让内层循环结构整体充当外层循环的循环体。若外层循环执行m次,内层循环执行n次,整个程序执行m*n次。
⑤格式:①初始化条件②循环条件③迭代部分④循环体
|
for(①;②;③){ ④ |
|
while(②){ ④ ③ |
|
do{ ④ ③ }while(②); |
【题目1】
打印下面图形
******
******
******
|
for(int i = 0;i < 3;i++){ for(int j = 0;j < 6;j++){ System.out.print("*"); } System.out.println(); |
说明:外层循环控制行数,内层循环控制列数
【题目2】输出100内的质数。(两种)
法一:
|
class TestPrimeNumber{ public static void main(String[] args){ boolean flag = false; long start = System.currentTimeMillis();//获取系统当前的毫秒数 for(int i = 2;i <= 100000;i++){//实现100以内的自然数的遍历 //如何判断i是否为一个质数 for(int j = 2;j <= Math.sqrt(i);j++){ if(i % j == 0){ flag = true; break; } } if(!flag){//if(flag == false){//System.out.println(i);} flag = false; } long end = System.currentTimeMillis(); System.out.println("所花费的时间为:" + (end - start)); //35535--加上break:10059--使用Math.sqrt():}} |
法二:
|
class TestPrimeNumber1{ public static void main(String[] args){ //boolean flag = false; long start = System.currentTimeMillis();//获取系统当前的毫秒数 l:for(int i = 2;i <= 100000;i++){//实现100以内的自然数的遍历 //如何判断i是否为一个质数 for(int j = 2;j <= Math.sqrt(i);j++){ if(i % j == 0){ //flag = true; //break; continue l;}} //if(!flag){//if(flag == false){ System.out.println(i); //} //flag = false;} long end = System.currentTimeMillis(); System.out.println("所花费的时间为:" + (end - start)); //35535--加上break:10059--使用Math.sqrt():}} |
4.2.4 无限循环结构
4.4.1 break
使用在循环结构中,一旦执行到continue,就跳出当次循环。
|
for(int i = 1;i <= 10;i++){ if(i % 4 == 0){ //break; //123 continue; //123567910 } System.out.print(i); } |
在嵌套循环中,使用带标签的break和continue,可通过标签指明要终止的是哪一层语句块。
label:for(int i = 1;i < 5;i++){
for(int j = 1;j <= 10;j++){
if(j % 4 == 0){
//break;
//continue;
//break label;
continue label;
}
System.out.print(j);
System.out.println();
4.4.3 return
5.1.1方法的定义格式
|
public class MethodTest02{ public static void main(String[] args){ //入口 //在main方法中对sumInt方法进行调用,完成功能. //注意:加有static的方法,调用的时候必须采用“类名.”的方式调用。 MethodTest02.sumInt(10,20); MethodTest02.sumInt(50,100); //调用 } //定义方法,完成两个整数的求和。 //注意:目前所有的方法请定义成public static . public static void sumInt(int a,int b){ int c = a + b; System.out.println(a + "+" + b +"=" +c); } |
|
public class MethodTest03{ public static void main(String[] args){ //入口 //方法调用. MethodTest03.println("Hello World"); //"Hello World" 是实际参数(实参) //方法调用 MethodTest03.m1(13,15); MethodTest03.m2(); //调用m3 int retValue = MethodTest03.m3(100,200); System.out.println("计算结果是:"+retValue);} //方法的定义 //方法的形式参数列表中起决定性作用的是参数的类型。 //参数的名字(局部变量的名字)是随意的只要是合法的标识符即可。 public static void println(String msg){ //String msg 是形式参数列表(形参) System.out.println(msg); } public static void m1(int a,int b){ System.out.println(a+"+"+b+"="+(a+b)); } public static void m2(){ System.out.println("呵呵"); } //该方法有返回值,程序必须使用return语句返回值。 public static int m3(int a,int b){ int c = a + b; return c; //程序执行到此处m3方法执行结束。并返回值c //return语句下面不能再有其他代码,因为根本无法执行到。 //System.out.println("ABC"); //编译无法通过。 } |
|
public class MethodTest04{ //入口 public static void main(String[] args){ A.m1(); //Error:在当前类中没有m1方法. //m1(); MethodTest04.m2(); //前提:在当前类中. //类名. 可以省略 m2(); } public static void m2(){ System.out.println("m2....."); } class A{ public static void m1(){ System.out.println("A's m1 method invoke!"); } |
|
public class MethodTest06{ public static void main(String[] args){ m1(0); System.out.println("ABC"); //以下程序编译可以通过。(程序分编译期和运行期,编译期只看语法不运算) if(true){ return; } System.out.println("bjpowernode"); } |
5.2方法的重载(overload)
①方法名相同
②方法的参数类型,个数,顺序至少有一个不同
③方法的返回类型可以不同(不依靠返回类型来区分重载)
④方法的修饰符可以不同,因为方法重载和修饰符没有任何关系
⑤方法重载只出现在同一个类中
5.2.2重载的优点:
5.3.1方法的执行原理
方法的递归调用就是方法自身调用自身。
以下程序因为递归没有结束的条件,所以一直压栈,没有弹栈,导致栈内存溢出错误!所以递归必须要有结束条件。
|
public class RecursionTest01{ //入口 public static void main(String[] args){ m1(); } public static void m1(){ m1(); //java.lang.StackOverflowError } |
【例题1】:不使用递归,计算1-N的求和。
|
public class RecursionTest02{ public static void main(String[] args){ int n = 5; //调用该方法完成1-N的求和 int retValue = method1(n); System.out.println(retValue); //15 } //该方法完成1-N的求和. public static int method1(int n){ int sum = 0; for(int i=0;i<=n;i++){ sum += i; } return sum; } |
【例题2】:使用递归,计算1-N的求和。
|
public class RecursionTest03{ public static void main(String[] args){ int n = 5; //调用该方法完成1-N的求和 int retValue = method1(n); System.out.println(retValue); //15 } //该方法完成1-N的求和. //1+2+3+4+5+...N public static int method1(int n){ if(n==1){ return 1; }else{ return n + method1(n-1); }}} |
【练习】:计算N的阶乘。两种方式:使用递归和不使用递归。
|
public class RecursionTest04{ public static void main(String[] rgs){ System.out.println(method1(5)); //120 } public static int method1(int n){ //不使用递归 int result = 1; for(int i=1;i<=n;i++){ result *= i; } return result; //使用递归 if(n==1){ return 1; }else{ return n * method1(n-1); } } |
7.1数组
public class TestArray {
public static void main(String[] args) {
int i1;
i1 = 12;
boolean b = true;
//1.如何定义一个数组
//1.1数组的声明
String[] names;
int scores[];
//【注】Java语言中声明数组时不能指定其长度(数组中元素的数), 例如: int a[5]; //非法
//1.2初始化
//第一种:静态初始化:初始化数组与给数组元素赋值同时进行。
names = new String[]{"周爽","郭强强","俞乾龙"};
//第二种:动态初始化:初始化数组与给数组元素赋值分开进行。
scores = new int[4];
//2.如何调用相应的数组元素:通过数组元素的下角标的方式来调用。
//下角标从0开始,到n -1 结束。其中n表示的数组的长度。
scores[0] = 87;
scores[1] = 89;
scores[3] = 98;
//3.数组的长度:通过数组的length属性。
System.out.println(names.length);//3
System.out.println(scores.length);//4
//4.如何遍历数组元素
for(int i = 0;i < names.length;i++){
System.out.println(names[i]);
}}}
//声明数组的错误写法:
1)String[] names = new String[5]{"AA","BB","CC"};//右边[ ]中的5不用写了
2)int i[10];//正确写法:int i[] = new int[10];
3)int i = new int[];//[ ]中要指明数组长度
【注】不管是动态还是静态初始化数组,一定在创建的时候,就指明了数组的长度!每个数组都有一个属性length指明它的长度,例如:a.length 指明数组a的长度(元素个数)。数组一旦初始化,其长度是不可变的。
关于数组元素的默认初始化值
//关于数组元素的默认初始化值:
1)byte short int long 而言:0
2)float double 而言:0.0
3)char而言:空格
4)boolean而言:false
5)引用类型变量而言:null
//初始化时的一些其他正确写法:
1.Int[] myInt; myInt = new int[]{1,2,3};
2.int[] myInt = {1,2,3};
// 错误:
int myInt;
myInt = {1,2,3};
//数组的内存结构
【练习1】
/*
1.(1)定义类Pritimive,在类中定义一个有3个元素的boolean类型的数组t作为其成员变量。数组元素未赋值。
定义类TestPritimive,在TestPritimive的main()方法中创建Pritimive对象d,输出其成员变量t的三个元素值。
练习目的:检验基本数据类型数组创建时的自动赋值。
(2)给对象d的成员变量t赋值为{true,true,true},并输出t的三个元素值。
*/
public class TestPritimive {
public static void main(String[] args) {
//创建Pritimive的对象d
Pritimive d = new Pritimive();
//遍历d的数组元素
for(int i = 0;i < d.t.length;i++){
System.out.println(d.t[i]);
}
//给d的数组元素重新赋值
d.t[0] = true;
d.t[1] = true;
d.t[2] = true;
for(int i = 0;i < d.t.length;i++){
System.out.println(d.t[i]);
}
}
class Pritimive{
boolean[] t = new boolean[3];
【练习2】
/* 从键盘读入学生成绩,找出最高分,并输出学生成绩等级。
成绩>=最高分-10 等级为’A’
成绩>=最高分-20 等级为’B’
成绩>=最高分-30 等级为’C’
其余 等级为’D’
提示:先读入学生人数,根据人数创建int数组,存放学生成绩。
*/
import java.util.Scanner;
public class TestStudentScore {
public static void main(String[] args) {
//1.创建Scanner的对象,并从键盘获取学生的个数n
Scanner s = new Scanner(System.in);
System.out.println("请输入学生的个数:");
int count = s.nextInt();//count用来记录学生的个数
//2.根据输入的学生的个数n,创建一个长度为n的int型的数组
int[] scores = new int[count];
int maxScore = 0;
//3.依次从键盘获取n个学生的成绩,并赋给相应的数组元素,并获取n个学生中的最高分
System.out.println("请输入" + count + "个成绩:");
for(int i = 0;i < scores.length;i++){
int score = s.nextInt();//依次从键盘获取学生的成绩
scores[i] = score;
if(scores[i] > maxScore){
maxScore = scores[i];
}
}
//4.遍历学生成绩的数组,并根据学生成绩与最高分的差值,赋予相应的等级,并输出
System.out.println("最高分为:" + maxScore);
for(int i = 0;i < scores.length;i++){
char level;
if(scores[i] >= maxScore - 10){
level = 'A';
}else if(scores[i] >= maxScore - 20){
level = 'B';
}else if(scores[i] >= maxScore - 30){
level = 'C';
}else{
level = 'D';
}
System.out.println("student " + i + " score is " + scores[i] + " grade is " + level);
}}}
//输出效果:
7.3二维数组
public class TestException {
public static void main(String[] args) {
//1.数组下标越界的异常:java.lang.ArrayIndexOutOfBoundsException
int[] i = new int[10];
i[0] = 90;
i[10] = 99;
for(int m = 0;m <= i.length;m++){
System.out.println(i[m]);
}
//2.空指针的异常:NullPointerException
//第一种:
boolean[] b = new boolean[3];
b = null;//b指向的地址变成null了,找不到b[0]了
System.out.println(b[0]);
//第二种:
String[] str = new String[4];
//str[3] = new String("AA");//str[3] = "AA";//没有这两句中的一句,就会出现异常
System.out.println(str[3].toString());
//第三种:
int[][] j = new int[3][];
j[2][0] = 12;
}
7.5数组的常用算法问题
1.求数组元素的最大值、最小值、平均数、总和等
【练习】定义一个int型的一维数组,包含10个元素,分别赋一些随机整数,然后求出所有元素的最大值,最小值,平均值,和值,并输出出来。
【代码】
public class TestArray3 {
public static void main(String[] args) {
int[] arr = new int[] { 12, 43, 9, 0, -65, -99, 100, 9 };
// 最大值
int max = arr[0];
for (int i = 1; i < arr.length; i++) {
if (max < arr[i]) {
max = arr[i];}}
System.out.println("数组的最大值为:" + max);
// 最小值
int min = arr[0];
for (int i = 1; i < arr.length; i++) {
if (min > arr[i]) {
min = arr[i];
}
}
System.out.println("数组的最小值为:" + min);
// 总和
int sum = 0;
for (int i = 0; i < arr.length; i++) {
sum += arr[i];
}
System.out.println("总和为:" + sum);
// 平均数
int avg = 0;
avg = sum / arr.length;
System.out.println("平均值为:" + avg);
【输出函数的快捷键】syso +alt+/
2.数组的复制、反转
【练习】
使用简单数组
(1)创建一个名为TestArray的类,在main()方法中声明array1和array2两个变量,他们是int[]类型的数组。
(2)使用大括号{},把array1初始化为8个素数:2,3,5,7,11,13,17,19。
(3)显示array1的内容。
(4)赋值array2变量等于array1,修改array2中的偶索引元素,使其等于索引值(如array[0]=0,array[2]=2)。打印出array1。
思考:array1和array2是什么关系?array2 = array1:表示将array1的地址值赋给了array2
拓展:修改题目,实现array2对array1数组的复制
【代码】修改array2的时候,array1也被改变了,类似“快捷方式”
public class TestArray {
public static void main(String[] args) {
int[] array1, array2;
array1 = new int[] { 2, 3, 5, 7, 11, 13, 17, 19 };
// 遍历array1
for (int i = 0; i < array1.length; i++) {
System.out.print(array1[i] + "\t");
}
System.out.println();
System.out.println(array1);
array2 = array1;
System.out.println(array2);
// 修改array2
for (int i = 0; i < array2.length; i++) {
if (i % 2 == 0) {
array2[i] = i;
}
}
// 遍历array1
for (int i = 0; i < array1.length; i++) {
System.out.print(array1[i] + "\t");
}}}
正确的复制方式:
public class TestArray3 {
public static void main(String[] args) {
int[] arr = new int[] { 12, 43, 9, 0, -65, -99, 100, 9 };
// 数组的复制
int[] arr1 = new int[arr.length];
for (int i = 0; i < arr1.length; i++) {
arr1[i] = arr[i];
}
// 数组元素的反转(逆序)
//方法一:
for(int i = 0;i < arr.length/2;i++){
int temp = arr[i];
arr[i] = arr[arr.length-1 - i];
arr[arr.length - 1 - i] = temp;
}
//方法二:
for (int x = 0, y = arr.length - 1; x < y; x++, y--) {
int temp = arr[x];
arr[x] = arr[y];
arr[y] = temp;
}
System.out.println("反转以后:");
// 遍历
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + "\t");
}}}
3.数组元素的排序(面试前看一看)
l 插入排序
- 直接插入排序、折半插入排序、希尔(Shell)排序
l 交换排序
- 冒泡排序、快速排序(或分区交换排序)
l 选择排序
- 简单选择排序、堆排序
l 归并排序
l 基数排序
public class TestArray3 {
public static void main(String[] args) {
int[] arr = new int[] { 12, 43, 9, 0, -65, -99, 100, 9 };
// 使用冒泡排序使数组元素从小到大排列
for (int i = 0; i < arr.length - 1; i++) {
for (int j = 0; j < arr.length - 1 - i; j++) {
if (arr[j] > arr[j + 1]) {
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;}
}
}
//使用直接选择排序使数组元素从小到大排列
for(int i = 0; i < arr.length - 1; i++){
int t = i; //默认i处是最小的
for(int j = i;j < arr.length;j++){
//一旦在i后发现存在比其小的元素,就记录那个元素的下角标
if(arr[t] > arr[j]){
t = j;}}
if(t != i){
int temp = arr[t];
arr[t] = arr[i];
arr[i] = temp;}
}
Arrays.sort(arr);
System.out.println("排序以后:");
// 遍历
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + "\t");
}}}