贰-流程控制与数组

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讲义》)    

猜你喜欢

转载自blog.csdn.net/qq_41979043/article/details/82969612