美文网首页寒桥笔记-Java
JAVA学习笔记(二)

JAVA学习笔记(二)

作者: 寒桥 | 来源:发表于2017-04-21 10:31 被阅读13次

    1.方法定义

    方法(Method)、函数(Function)其实就是指一个特定的功能操作
    如果方法使用了static修饰,此时我们使用方法所在的类的名称,方法名(参数)
    如果方法没有使用static修饰,此时我们将使用方法所在类的对象来调用
    static表示方法属于类,直接使用类名调用即可

    2.方法中的术语

    修饰符:public.static等;static修饰的方法属于类,直接使用类名调用即可
    返回值类型:方法其实是在完成一个功能,该功能操作完毕之后,是否需要给调用者返回一个结果.如果不需要给调用者返回结果,此时关键字void来声明,表示没有返回值;
    方法名称:遵循标识符的规范,使用动词表示,首字母小写,若是多个单词组成,使用驼峰表示法;
    形式参数:方法圆括号中的变量,仅仅只是占位而已,参数的名称其实无所谓,形式参数可以有多个;
    参数列表:参数列表==参数的类型+参数的个数+参数的顺序;
    方法签名:方法签名==方法名称+方法参数列表;(在同一类中,方法签名是唯一的.否则编译报错)
    方法体:方法中{}中的代码,表示具体完成该功能的代码;
    返回值:在方法内部,使用return关键字;(功能1:给调用者返回一个结果值,此时该方法不能使用void修饰.功能2:结束当前方法.)

    3.方法的重载(overload)

    重载方法的定义是在同一个类中,某方法允许存在一个以上的同名方法,只要它们的参数列表不同即可
    方法重载的作用:屏蔽了统一供能的方法由于参数列表不同所造成的方法名称不同
    方法重载判断原则:“两同一不同”
    两同:同类中,方法名相同
    一不同:方法参数列表不同(参数类型、参数个数、参数顺序)
    注意:方法重载和方法的返回值类型无关,只是一般要求返回值类型一致

    打印方法的重载.png 判断重载的原则.png
    public class MethodDemo {
        // 求两个整数之和
        static int getSum (int a, int b) {
            return a + b;
        }
    
        // 求两个小数之和
        static double getSum (double a, double b) {
            return a + b;
        }
    
        public static void main(String[] args) {
            // 实际这个打印方法也是重载
            System.out.println(MethodDemo.getSum(1, 3));;
            System.out.println(MethodDemo.getSum(1.3, 2.4));;
        }
    }
    

    4.JVM内存模型

    JWM内存划分,人为的根据不同内存空间的存储特点以及存储的数据:

    图片.png

    <strong>程序计数器</strong>:当前线程所执行的字节码的行号指示器.
    <strong>本地方法栈</strong>:为虚拟机使用的native方法服务.
    <strong>java虚拟机栈</strong>:描述java方法执行的内存模型,每个方法被执行的时候都会同时创建一个栈帧用于存储局部变量表,操作栈,动态链接,方法出口等信息.每一个方法,创建一个栈帧,栈帧存放了当前方法的数据信息.(局部变量),当方法调用完毕,该方法的栈帧就被销毁了.
    <strong>Java堆</strong>:被所有线程共享的一块内存区域,在虚拟机启动时创建.所有的对象实例以及数组都要在堆上分配(使用new关键字,就表示在堆中开辟一块新的存储空间).
    <strong>方法区</strong>:线程共享的内存区域,存储已被虚拟机加载的类信息,常量,静态常量即时编译器编译后的代码数据等(这个区域的内存回收目标主要针对常量池的回收和对类型的卸载).
    <strong>GC(Garbage Collection)</strong>:垃圾回收器.
    java的自动垃圾回收机制:简单理解为.程序员就不需要手动的去控制内存的释放.当JVM发觉内存资源紧张的时候,就会自动地去清理无用对象(没有被引用到的对象)所占用的内存空间.

    5.数组

    基本数据类型:byte,short,int,long,float,double,char,boolean
    引用数据类型:类,接口,数组
    数组的定义:
    方式1:数组的元素类型[] 数组名;int[] ages; (推荐使用这种写法,可以把int[]看成是一种数据类型,int类型的数组类型)
    方式2:数组元素的类型 数组名[];int ages[];
    数组必须先初始化,才能使用,因为初始化表示在内存中分配空间

    6.数组的静态初始化和内存分析

    JAVA中数组必先初始化才能使用,所谓初始化就是给数组元素分配内存,并为每个元素赋初始值.
    初始化数组的两种方式:静态初始化和动态初始化;
    注意:无论以哪种方式初始化数组,一旦初始化完成,数组的长度就固定了,不能改变,除非重新初始化.也就是说数组是定长的.

    数组的静态初始化操作
    特点:由我们自己来为每一个数组元素设置初始化值,而数组的长度由系统决定.
    语法:数组元素类型[] 数组名= new 数组元素类型[]{}(元素1,元素2,元素3......);
    举例:
    int [] nums = new int[]{1,3,5,7,9};
    简单写法:必须声明之后立刻初始化,不能先声明后初始化
    int [] nums = {1,3,5,7,9};

    new关键字:在堆空间开辟一块内存区域,用来存储数据.
    nums引用于堆空间中内存地址为0x1234这块区域.
    我们表面上操作nums,其实底层操作是0x1234这块区域;
    int[] nums=new int[]{1,3,5,7,9};
    System.out.println(nums.length);

    当在堆中重新开辟一个新空间如0x3456,赋值给nums,那么在栈中,nums的引用就回复改之前的0x1234变成0x3456,堆中0x1234空间就变成了垃圾,等待垃圾回收机制释放。
    nums = new int[]{2,4,8};
    System.out.println(nums.length);

    如果要想让现在的引用0x3456也变成垃圾,直接将nums = null,null表示没有引用任何内存空间。若堆中的内存空间没有被引用的时候就变成了垃圾,等待垃圾回收器的回收


    存储展示.png

    7.操作数组常见异常

    NullPointerException:空指针异常(空引用).
    当数组还未进行初始化,就直接操作数组.
    String[ ] bs = null;
    System.out.println(bs.length)
    ArraylndexOutOfBoundsException:数组的索引越界异常

    8.main方法的数组参数

    public class ArrayDemo {
    public static void main(String[] args) {

    }
    

    }
    main方法是static修饰的,说明直接使用ArrayDemo类调用即可。在底层JVM底层通过ArrayDemo.main(new String[]{})运行
    main方法的String数组参数,其实是暴露给程序运行者的,用于给程序传递一个数据信息。

    9.增强for循环foreach

    在使用循环迭代数组的时候,往往不关心迭代变量(数组的索引),这时候可以使用foreach,通过反编译工具查看字节码,发现foreach其实在底层还是通过for循环+索引来操作数组的,我们把增强for循环称之为编译器的新特性(而不是底层的),就是一个语法糖(让开发者写更少、更简单的代码实现相同的功能)

    10.冒泡排序:Bubble Sort

    基本思路:对未排序的各元素从头到尾依次比较相邻的两个元素的大小,若大于则交换位置,经过第一轮比较排序后得到最大值,然后使用相同的方法把剩下的元素逐个比较即可。
    可以看出若有N个元素,那么一共要进行N-1轮比较,第M轮要进行N-M次比较

    public class MyClass {
        public static void main(String[] args) {
            // 冒泡排序
            int[] array = {2, 9, 6, 7, 4, 1};
            printArray(array);
            bubbleSort(array);
            printArray(array);
    
        }
    
        static void bubbleSort(int[] arr) {
            for (int i = 1; i <= arr.length-1; i++) {
                for (int j = 1; j <= arr.length - i; j++) {
                    if (arr[j - 1] > arr[j]) {
                        swap(arr, j-1, j);
                    }
                }
            }
        }
        
        // 打印数组
        static void printArray(int[] arr) {
            if (arr == null) {
                System.out.println("null");
                return;
            }
            System.out.print("[");
            for (int i = 0; i < arr.length; i++) {
                System.out.print(arr[i]);
                if (i != arr.length-1) {
                    System.out.print(", ");
                }
            }
            System.out.println("]");
        }
    
        // 交换数组中的两个元素
        static void swap(int[] arr, int index1, int index2) {
            int temp = arr[index1];
            arr[index1] = arr[index2];
            arr[index2] = temp;
        }
    }
    
    

    11.选择排序:Selection Sort

    基本思路:选择某个索引位置的元素,然后和后面元素依次比较,若大于刚交换的位置,经过第一轮比较排序后可得出最小值,然后使用同样的方法把剩下的元素逐个比较即可。
    可以看出选择排序,第一轮选出最小值,第二轮会选出第二小的值,直到最后。N个数要进行N-1轮,选择排序每一轮只进行一次交换,相对于冒泡排序效率高一些

    // 该代码也不是最正确的选择排序
    public class MyClass2 {
        public static void main(String[] args) {
            // 选择排序
            int[] array = {2, 9, 6, 7, 4, 1};
            printArray(array);
            selectionSort(array);
            printArray(array);
    
        }
       
        static void selectionSort(int[] arr) {
            for (int i = 1; i <= arr.length-1; i++) {
                for (int j = i; j <= arr.length - 1; j++) {
                    if (arr[i - 1] > arr[j]) {
                        swap(arr, i-1, j);
                    }
                }
            }
        }
    

    12.数组的搜索算法:从指定数组中去搜索某个元素的索引值是多少

    方式一:线性搜索(从头到尾/从尾到头):indexOf()/lastIndexOf()
    对于元素过多的数组,性能超低:有N个元素,循环次数=(N+1)/ 2
    方式二:二分搜索法/二分查找法/折半查找
    前提是数组元素必须有序
    两者比较:当数据量很大适宜采用二分搜索法。采用二分搜索法查找时,数据需要时排序好的

    public class MyClass3 {
        public static void main(String[] args) {
            int[] array = {1, 2, 3, 4, 5, 6, 7, 8, 9};
            // 二分法查找数组中的某个元素位置
            int index = binarySearch(array, 8);
            System.out.println(index);
        }
    
        static int binarySearch(int[] arr, int key) {
            int low = 0; // 最低的索引;
            int high = arr.length - 1; // 最大的索引
            while (low <= high) {
                int mid = (low + high) >> 1; // 操作二进制,相当于是除以2
                // int mid = (low + high) / 2;
                int midVal = arr[mid]; // 中间的元素,猜测的值
                if (midVal > key) {
                    // 猜大了
                    high = mid - 1;
                } else if(midVal < key) {
                    // 猜小了
                    low = mid + 1;
                } else {
                    return mid;
                }
            }
            return -1;
        }
    

    相关文章

      网友评论

        本文标题:JAVA学习笔记(二)

        本文链接:https://www.haomeiwen.com/subject/lwblzttx.html