JAVA学习笔记(二)

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

程序计数器:当前线程所执行的字节码的行号指示器.
本地方法栈:为虚拟机使用的native方法服务.
java虚拟机栈:描述java方法执行的内存模型,每个方法被执行的时候都会同时创建一个栈帧用于存储局部变量表,操作栈,动态链接,方法出口等信息.每一个方法,创建一个栈帧,栈帧存放了当前方法的数据信息.(局部变量),当方法调用完毕,该方法的栈帧就被销毁了.
Java堆:被所有线程共享的一块内存区域,在虚拟机启动时创建.所有的对象实例以及数组都要在堆上分配(使用new关键字,就表示在堆中开辟一块新的存储空间).
方法区:线程共享的内存区域,存储已被虚拟机加载的类信息,常量,静态常量即时编译器编译后的代码数据等(这个区域的内存回收目标主要针对常量池的回收和对类型的卸载).
GC(Garbage Collection):垃圾回收器.
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;
    }
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,634评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,951评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,427评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,770评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,835评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,799评论 1 294
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,768评论 3 416
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,544评论 0 271
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,979评论 1 308
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,271评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,427评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,121评论 5 340
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,756评论 3 324
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,375评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,579评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,410评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,315评论 2 352

推荐阅读更多精彩内容

  • Java的数据类型 $$2 + 5$$ Java是一门纯粹的面向对象编程语言,除了8个基本数据类型不是对象以外,其...
    xuzhougeng阅读 387评论 2 3
  • 1.十进制-->二进制:十进制转为二进制主要是对十进制数进行除2运算 2.二进制-->十进制:二进制乘以2的过程 ...
    晨星资源阅读 391评论 0 0
  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 31,621评论 18 399
  • 泛型 泛型可以解决数据类型的安全问题,其主要原理是在类声明时通过一个标识表示类中某个属性的类型或者是某个方法的返回...
    翌日千里阅读 756评论 0 2
  • 每个人总会有一些时候会受到恐惧的困扰,但是恐惧并不是坏事,因为有了恐惧,人类才会注重去保护自己。 同其它情绪一样,...
    蔡彦宏阅读 1,102评论 0 1