Scanner类位于java.util包中 Scanner x = new Scanner(System.in); int a = x.nextInt();
debug:直接在源代码选择断点,然后debug运行到断点! !
1.循环/判断语句杂谈
①if else后若只有单行语句,则不用括起来,但保留花括号可读性高,减少错误发生。
if(a>18)
System.out.println("你该独立了 亲爱的");
a++;
else
System.out.print("感受青春吧");
这段代码中if后的条件执行体省略了花括号,则系统只把第一句作为条件执行体,当第一句结束后,if语句也结束了。
后面的一条a++;变成了普通的代码,从而导致else语句没有if语句,从而引起编译错误。
if... else if...else if...else...范围有小到大表示,便于筛选。
if只是判断语句,非循环;
②switch语句:
在java里面byte short char int 枚举类型 java.lang.String类型(StringBuilder/StringBuffer不可以)都可以写在里面!
别忘了每个case后面的break;!!
可以把功能相同的case语句合并起来,如:
③while();
陷入死循环,相当循环体是空语句。若没有括号,同样循环体在第一个;处结束。
④for( ; ; );
死循环,第二条语句默认为true!
for循环允许同时指定多个初始化语句(变量有相同的数据类型,因为只能有一个声明语句)
循环条件也可以是一个包含逻辑运算符的表达式。
for循环,循环条件总比循环体多一次,其中变量作用域在内部。
for循环变量初始化和循环变量变化部分,可以是使用","同时初始化或改变多个循环变量的值,如:
for(int i=1,j=5;i<=5;i++,j--){
System.out.print(i+"+"+j+"="+(i+j)+" ");
}
System.out.println();
for(int i=1,j=5;i<=5;++i,--j){
System.out.print(i+"+"+j+"="+(i+j)+" ");
}
// 1+5=6 2+4=6 3+3=6 4+2=6 5+1=6。
// 1+5=6 2+4=6 3+3=6 4+2=6 5+1=6。
所以for循环是先执行"表达式1",再进行"表达式2"的判断,判断为真则执行"循环体",循环体执行完以后执行表达式3。
代码中,初始化变量部分同时对两个变量i和j赋初值,循环变量变化部分也同时对两个变量进行变化,运行结果如上。
但是判断条件部分可以用&/|连接,不可以写几个判断条件部分!
不要在循环体内轻易修改循环变量的值。若实在需要,可以定义一个临时变量,先将循环变量的值赋给临时变量,然后对临时变量进行修改。
for循环的循环条件总是比循环体多执行一次。
使用for循环时,也可以把初始化条件定义在循环体之外(扩大初始化变量的作用域,也可以通过设置临时变量的方法改变,效果更好)。
把迭代语句放在循环体内时,和while功能一样。
OK:
for(){
for(){
break OK;标签放在循环语句之前。
}// 直接跳出两层循环。
}
continue(直接开始下一次循环),break(终止循环本身)只跳for,while,do-while,for-each循环;
OK:
for(int i=0;i<5;i++){
for(int j=0;j<3;j++){
System.out.print("i的值是:"+i+"j的值是:"+j);
if(j==1){
continue OK;
}
}
}
循环变量j的值将无法超过1。
当j等于1时continue OK;
语句就结束了外层循环的当次循环,直接开始下一次循环,内层循环没有机会执行完成。
⑤return(结束整个方法 不管处在多少个循环内)。
2.一维数组
①数组基础:数组是编程语言中最常见的一种数据结构,可以存储多个数据,每个数组元素存放一个数据,通常可通过数组元素的索引来访问数组元素。
包括为数组元素赋值和取出数组元素,java的数组要求所有的数组元素具有相同的元素类型。
(就算水果数组里可以存放苹果,西瓜类型的元素,但它还是水果类型。)
②数组的创建:
a.静态初始化:
int[ ] name = {......};// 左边定义、右边初始化、等号赋值。
或者:int[ ] name = new int[ ]{......};
b.动态初始化:
int[] b=new int[4];
被自动赋值 int型赋值为零 引用类型赋值为null 浮点型赋值为0.0 Boolean类型赋值false char型'\u0000'。
int[ ]是引用类型。
不能同时采用静态初始化和动态初始化。
数组的第一个索引值是0,最后一个是a.length-1。
b.length;a.length;没有括号!
ps:如果访问数组元素时指定的索引值<0,或者大于等于数组的长度,编译程序时不会出现错误,但运行时出现异常: java.lang.ArrayIndexOutOfBoundsException:N。数组索引越界异常,N是指程序员试图访问的数组索引。
int[] a= {5,6,7};
int[] b=new int[4];// 可采用循环的方式为每一个数组元素赋值。
for(int i=0;i<a.length;i++)
{
b[i]=a[i];// 数组元素的赋值。
System.out.println(b[i]);
}//5 6 7
System.out.println(b[3]);// 0 指向不变。
System.out.println(a==b);// false。
System.out.println("b的数组长度是"+b.length);// 4。
b=a;//b和a指向了同一个堆内存!把a的指向地址值赋给了b!让b指向a所指向的地址。
System.out.println(a==b);// true。
System.out.println("b的数组长度是"+b.length);// 3。
3.foreach循环
从Java5之后,Java提供了一种更简单的循环:foreach循环。
这种循环遍历数组和集合更加简洁。
使用时,无须获得数组和集合长度,无须根据索引来访问数组元素和集合元素,自动遍历每个元素。
for(int i:a){
System.out.println(i);
}
int a[]={1,2,3,4,5};
for(int i:a){
i=i+1;
System.out.println(i);// 2 3 4 5 6。
}
使用foreach循环遍历数组,迭代数组的每个元素。
foreach中的循环变量相当于一个临时变量,系统会自动把数组变量依次赋给这个临时变量。
并不能改变数组元素的值,可以临时在一个foreach中赋值,但是之后就没用了。
for(int i:a){
System.out.println(i);// 1 2 3 4 5。
}
4.引用类型数组
①数组是一种引用数据类型,数组元素和数组变量在内存中是分开存放的,数组是管理者。
数据引用变量只是一个引用,这个引用变量可以指向任何有效的内存,只有当该引用指向有效内存后,才可以通过该数组变量来访问数组元素。
引用变量是访问真实对象的根本方式!数组引用变量是访问堆内存中数组元素的根本方式。
如果引用该数组对象的数组引用变量是一个局部变量,那么它应该被储存在栈内存中,当每一个方法执行时,都会建立属于自己的栈内存,执行结束栈内存销毁。运行程序时的数据区为堆内存,实际的数组对象被存储在堆内存中(对象的创建成本比较大)。
其中的对象当没有任何引用变量引用它时,系统的垃圾回收器才会在合适的时候回收它。
如果数组类型相互兼容,就可以让一个数组变量指向另一个实际的数组,这种操作会让人产生数组的长度可变的错觉。
如第2点例代码。
public static void main(String[] args){
Person[] students = new Person[2];
// 定义一个Person数组,接着动态初始化这个Person数组。
Person zheng = new Person();// Person实例,将这个实例赋给zheng变量。
// zheng变量名在栈区。
zheng.age=18;
zheng.height=172;
// 堆内存中存储这两个数据,栈区的变量名指向这两个数据。
students[0]=zheng;
// 栈内存中students指向的堆内存中的第一个格子里不再是null,且其指向堆内存中被zheng指向的两个数据。
Person wei = new Person();
wei.age=18;
wei.height=158;
students[0].info();
// 当将students[0]=zheng;后,其与下一行代码相同。
// 堆内存的这两个数据,即堆内存中的students[0]指向,又被自己在栈内存中的变量名指向。
wei.info();
}
②与基本类型的不同。因为引用类型数组的数组元素是个引用,其引用变量也要放在栈内存。
③字符串数组:
String[][] str2 = { new String[3],new String[]{"hello"}};
str2[0][1]="nmv";
System.out.println(str2[0][1]);// nmv。
System.out.println(str2[1][0]);// hello。
System.out.println(str2[0][0]);// null。
String[][] str3 = { new String[3],new String[4],new String[5]};
str3[0][1]="b1";
str3[1][3]="d2";
str3[2][4]="e3";
System.out.println(str3[0][1]);// b1。
System.out.println(str3[1][3]);// d2。
System.out.println(str3[2][4]);// e3。
5.二维数组:
实质是一维数组的再引用,如果从数组底层的运行机制上来看,没有多维数组。
即(int[ ]是一个引用类型 ) [ ]数组元素里保存的引用指向一维数组。
a.数据类型[ ][ ] 数组名 = new 数据类型[行数][列数];
如:定义一个两行三列的二维数组:int[ ][ ] num = new int[2][3];
b.数据类型[ ][ ] 数组名; 数组名 = new 数据类型[行数][列数];
//二维数组的两种定义
//1.直接定义二维数组:
int[][] c = new int[5][6];
System.out.println(c[0]);// null。
System.out.println(c[0][0]);// 0。
直接定义为二维数组时 栈内存中为变量c
c指向堆内存中1个长度为5的一维数组,一维数组中的每个小格指向一个长度为6的一维数组。
//2.化为一维数组;一维数组的每个元素为引用数组类型!
int[][] d;
d= new int[3][];
System.out.println(d[2]);// null。
d[2]= new int[3];
d[2][0]=6;
System.out.println(d[2][0]);// 6。
System.out.println(d[2][2]);// 0。
先定义为一维数组形式时,栈内存中:d 堆内存:d[0](null) d[0](null) d[0](null)
不能直接的d[0]=1;这样赋值,没有任何意义!
System.out.println(d[2]);// [I@3c679bde,也许是地址。
d[2]=new int[3],说明堆内存中null指向=三个小格d[2][0](0) d[2][1](0) d[2][2](0)!
此时的d[2]已不再是null,是一个地址。而d[0],d[1]还是null,想变成二维数组,还需创建。
6.java增强的工具类
java.util.Array类 :
package 理解基础;
//java8提供的Array类里包含的一些static修饰的方法可以直接操作数组。
import java.util.Arrays;
public class Array {
public static void output(int[] array) {
for (int i = 0;i<array.length;i++){
System.out.print(array[i]+" ");
}
System.out.println();
/*for (int i :array){
System.out.print(array[i]+" ");
}// foreach不能用!因为传进来的是整个数组!不是一个一个元素。
*/
}
public static void main(String[] args){
// 1.对数组排序!
int[] a = new int[] {5,6,2,1,3,8};
Arrays.sort(a);// 全部排序。
Array.output(a); // 1 2 3 5 6 8。
// 对b的索引的2-4排序。
int[] b = new int[] {5,6,2,1,3,8};
Arrays.sort(b,2,4);
Array.output(b);
// 2.使用二分搜索算法查找指定元素所在的下标(必须是排序好的,否则结果不正确)。
Arrays.sort(a);
System.out.println("元素1在array1中的位置:"+Arrays.binarySearch(a, 1));
System.out.println("元素9在array1中的位置:"+Arrays.binarySearch(a, 9));
// 如果不存在返回负数。
// 位置是从0开始找的。
// 比较数组元素是否相等(顺序同):
int[] a2 = {1,2,3,5,6,8};
int[] a3 = {5,6,2,1,3,8};
System.out.println(Arrays.equals(a, a2));// true。
System.out.println(Arrays.equals(a, a3));// false。
// 3.填充数组,全部填充成5。
int[] c = new int[5];
Arrays.fill(c, 5);
Array.output(c);
// 将第0,1,2,3个元素赋值为6。
Arrays.fill(c, 0, 4, 6);// 第0个元素开始到第4个元素之前。
System.out.println("将数组的第0,1,2,3个元素赋值为6:Arrays.fill(c,0,4,6):");
Array.output(c);
//等等!
}
该类中包含了一些方法用来直接操作数组,比如可直接实现数组的排序、搜索等。
将数组转换为字符串,语法:Arrays.toString(数组名);
可以使用toString( )方法将一个数组转换成字符串,该方法按顺序把多个数组元素连接在一起,多个元素之间使用逗号和空格隔开(不是字符串数组!)如:
int[ ] num = new int[]{25,7,8,12};
String s = Arrays.toString(num);
System.out.println(s);
// 运行结果为:[25,7,8,12]。
可网上查看Arrays类的API 进一步运用:p101-106(《疯狂Java讲义》)