hashCode、匿名内部类、部分数组

这篇博客详细介绍了Java中的哈希码方法,解释了其与对象内存地址的关系。接着讨论了匿名内部类的概念、分类及其优缺点。此外,文章深入探讨了数组这一数据结构,包括其作为引用类型、存储特性、长度不变性以及数组操作的效率问题。还提供了多个代码示例来展示这些概念的应用。
摘要由CSDN通过智能技术生成

2021.02.14
第九次记录
情人节和大年初三重叠的一天
今天主要学习hashCode、匿名内部类、部分数组(数组没学完)
课堂笔记1:
/*
object类中的hashcode方法:
1.源代码:
public int hashCode()
2.这个方法不是抽象方法,带有native关键字,底层调用的是C++程序。
3.hashCode返回对象的哈希码值:
实际上就是一个java对象的内存地址,经过哈希算法,得出的一个值。
所以hashCode()方法的执行结果可以等同看做一个java对象的内存地址。
*/
代码演示1:

 public class AbouthashCode {
    public static void main(String[] args) {
        Object o = new Object();
        System.out.println(o.hashCode());
        MyClass mc = new MyClass();
        System.out.println( mc.hashCode());
    }
}
class MyClass {

}

输出结果:
1956725890
356573597
课堂笔记2:
/*
匿名内部类:
1.内部类:在类的内部又定义了一个新的类。
2.内部类的分类:
静态内部类:类似于静态变量;
实例内部类:类似于实例变量;
局部内部类:类似于局部变量;
3.注意:使用内部类编写的代码可读性差,能不用尽量不用。
4.匿名内部类是局部内部类的一种。
因为这个类没有名字,得名匿名内部类
5.学习匿名内部类主要是以后看到别人这样写代码的时候能够理解。
并不代表以后都要这样写。因为匿名内部类有两个缺点:
第一:太复杂,太乱,可读性差
第二:类没有名字,以后向重复使用,不能用
*/
代码演示2:

class 匿名内部类 {
    //由于前面有static,被称为“静态内部类”
    static class Inner1 {

    }
    //没有static,被称为“实例内部类”
    class Inner2 {

    }
    public void dosome(){
        //局部内部类
        class Inner3 {

        }
    }
    public void doOther(){

    }

    public static void main(String[] args) {
        Mymath mm = new Mymath();
       // ComputeUmpl cu = new ComputeUmpl();
        //mm.mysum(new ComputeUmpl(), 100, 200);
       mm.mysum(new Compute(){
           //这就叫匿名内部类
           public int sum(int a, int b) {
               return a + b;
           }
       }, 100, 200);
    }
}
//负责计算的接口
interface Compute {
    //抽象方法
    int sum(int a, int b);
}
/*
class ComputeUmpl implements Compute {
    public int sum(int a, int b){
        return a + b;
    }
}
*/
//数学类
class Mymath {
    //数学求和方法
    public void mysum(Compute c, int x, int y){
        int retValue = c.sum(x, y);
        System.out.println(x + "+" + y + "=" + retValue);
    }
}

输出结果:
100+200=300
课堂笔记3:
/*
Array
1.java中的数组是一种引用数据类型。不属于基本数据类型。数组的父类是Object类。
2.数组实际上是一个容器,可以同时容纳多个元素。(数组是一个数据的结合)
数组:字面意思是“一组数据”
3.数组当中可以存储基本数据类型的数据,也可以存储引用数据类型数据。
4.数组因为是引用数据类型,所以数组对象是在堆内存当中。(数组是存储在堆当中的)
5.数组当中如果存储的是“java对象”的话,实际上存储的是对象的“引用(内存地址)”。
6.数组一旦创建,在java中规定,长度不可变。(数组长度不可变)
7.数据的分类包括:一维数据、二维数组、三维数组、多维数组…(一维数组较多,二维数组偶尔使用)
8.所有的数组对象都有Length属性(java自带的),用来获取数组元素中的个数。
9.java中的数组要求数组中的元素统一。比如int类型数组只能存储int类型。
10.数组在内存方面存储的时候,数组中的元素内存地址(存储的每一个元素都是有规则的挨着排列的)
是连续的。内存地址连续。这是数组存储元素的特点(特色)。数组实际上是一种简单的数据结构。
11.所有的数组都是拿“第一个小方框的内存地址”作为整个数组对象的内存地址。
(数组中首元素的内存地址作为整个数组的内存地址)
12.数组中每一个元素都是有下标的,下标从0开始,以1递增,最后一个下标是:length - 1
下标非常重要,因为我们对数组中元素进行“存取”的时候,都需要通过下标来进行。
13.数组这种数据结构的优点和缺点是什么?
优点:查询/查找/检索某个下标上的元素时效率极高。可以说是查询效率最高的一个数据结构。
为什么检索效率高?
第一:每一个元素的内存地址在空间存储上是连续的。
第二:每一个元素类型相同,所以占用空间大小一样。
第三:知道第一个元素内存地址,知道每一个元素占用空间的大小,又知道下标,所以
通过一个数学表达式就可以计算出某个下标上元素的内存地址。直接通过内存地址定位
元素,所以数组的检索效率是最高的。
数组中存储100个元素,或者存储100万个元素,在元素查询/检索方面,效率是相同的,
因为数组中元素查找的时候不会一个一个找,是通过数学表达式计算出来的。
缺点:
第一:由于为了保证数组中每个元素的内存地址连续,所以在数组上随机删除或者增加元素的时候,
效率较低,因为随机增删元素会涉及到后面元素统一向前或者向后位移的操作。
第二:数组不能存储大数据量,因为很难在内存空间上找到一块特别大的连续的内存空间。
注意:对于数组中最后一个元素的增删,是没有效率影响的。
14.怎么声明/定义一个一维数组:
语法格式:
int[] array1;
double[] array2;
boolean[] array3;
String[] array4;
Object[] array5;
15.怎么初始化一个一维数组呢?
包括两种方式:静态初始化一维数组、动态初始化一维数组
静态初始化一维数组语法格式:
int[] array = {100,1,565,486,22};
动态初始化一维数组语法格式:
int[] array = new int[5]; 这里的5表示数组的元素个数
初始化一个5个长度的int类型数组,每个元素默认值为0
String[] array = new String[6]; 初始化6个长度的String类型数组,每个元素默认值为null
15.什么时候使用静态初始化方式,什么时候使用动态初始化方式
当你创建数组的时候,确定数组中存储哪些具体的元素时,采用静态初始化方式
当你创建数组的时候,不确定将来数组中存储哪些具体的元素时,可以采用动态初始化方式,预先分配内存空间。
*/
代码演示3:

public class ArrayDemo01 {
    public static void main(String[] args) {
        //声明一个int类型的数组,使用静态初始化的方式
        int[] a = {1, 100, 10, 20, 55, 689};
        //所有数据对象都有length属性
        System.out.println("数组中元素的个数:" + a.length);
        //数组中每一个元素都有下标
        //通过下标对数组中的元素进行存和取
        //取(读)
        System.out.println("第一个元素:" + a[0]);
        System.out.println("最后一个元素:" + a[a.length - 1]);
        System.out.println("-------我是分割线-------");
        //存(改),把第一个元素修改为111
        a[0] = 111;
        //把最后一个元素修改为0
        a[a.length - 1] = 0;
        System.out.println("第一个元素:" + a[0]);
        System.out.println("最后一个元素:" + a[a.length - 1]);
        System.out.println("-------我是分割线-------");
        //一维数组怎么遍历
        for (int i = 0; i < a.length; i++){
            System.out.println(a[i]); //i是从0到5,是下标
            //System.out.println(a[6]); //ArrayIndexOutOfBoundsException数组下标越界异常
        }
        System.out.println("-------我是分割线-------");
        //从最后一个元素遍历到第一个元素
        for (int i = a.length - 1; i >= 0; i--){
            System.out.print(a[i] + ";");
        }
    }
}

输出结果:
数组中元素的个数:6
第一个元素:1
最后一个元素:689
-------我是分割线-------
第一个元素:111
最后一个元素:0
-------我是分割线-------
111
100
10
20
55
0
-------我是分割线-------
0;55;20;10;100;111;
代码演示4:

public class ArrayDemo02 {
    public static void main(String[] args) {
        //声明/定义一个数组,采用动态初始化的方式
        int[] a = new int[4]; //创建长度为4的int数据,数组中每个元素的默认值为0
        //遍历数组
        for (int i = 0; i < a.length; i++) {
            System.out.println("数组中下标为" + i + "的元素是:" + a[i]);
        }
        System.out.println("-------我是分割线-------");
        //初始化一个Object类型的数组,采用动态初始化方式
        Object[] ob = new Object[3]; //3个长度,动态初始化,每个元素的默认值为null
        for (int i = 0; i < ob.length; i++) {
            System.out.println(ob[i]);
        }
        System.out.println("-------我是分割线-------");
        String[] strs = new String[3];
        for (int i = 0; i < strs.length; i++){
            System.out.println(strs[i]);
        }
        //采用静态初始化的方式
        System.out.println("-------我是分割线-------");
        String[] strs2 = {"ab", "ac", "ad"};
        for (int i = 0; i < strs2.length; i++){
            System.out.println(strs[i]);
        }
        System.out.print("strs2的长度为:" + strs2.length + "," + "元素分别是:");
        System.out.println(strs2[0] + "," + strs2[1] + "," + strs2[strs2.length - 1]);
    }
}

输出结果:
数组中下标为0的元素是:0
数组中下标为1的元素是:0
数组中下标为2的元素是:0
数组中下标为3的元素是:0
-------我是分割线-------
null
null
null
-------我是分割线-------
null
null
null
-------我是分割线-------
null
null
null
strs2的长度为:3,元素分别是:ab,ac,ad
代码演示5:

public class ArrayDemo03 {
    public static void main(String[] args) {
        int[] x = {1, 2, 3, 4};
        printArray(x);
        String[] printArray = {"ad", "ac", "ad"};
        printArray(printArray);
    }
    public static void printArray(int[] array){
        for (int i = 0; i < array.length; i++) {
            System.out.println(array[i]);
        }
    }
    public static void printArray(String[] args){
        for (int i = 0; i < args.length; i++) {
            System.out.println(args[i]);
        }
    }
}

输出结果:
1
2
3
4
ad
ac
ad
代码演示6:

//当一个方法的参数是一个数组的时候,还可以采用这种方式传
public class ArrayDemo04 {
    public static void main(String[] args) {
        //静态初始化一维数组
        int[] a = {1, 2, 3};
        printArray(a);
        System.out.println("-------我是分割线-------");
        // printArray({1, 2, 3}); 没有这种语法
        //如果直接传进一个静态数组的话,语法必须这样写
        printArray(new int[]{1, 2, 3});
        System.out.println("-------我是分割线-------");
        //动态初始化一维数组
        int[] b = new int[3];
        printArray(b);
        System.out.println("-------我是分割线-------");
        printArray(new int[3]);
    }
    public static void printArray(int[] array){
        for (int i = 0; i < array.length; i++) {
            System.out.println(array[i]);
        }
    }
}

输出结果:
1
2
3
-------我是分割线-------
1
2
3
-------我是分割线-------
0
0
0
-------我是分割线-------
0
0
0
代码演示7:

/*
main方法上面的“String[] args”有什么用
分析谁负责调用main方法--->JVM
JVM调用main方法的时候,会自动传一个String数组过来
所以main方法上面的“String[] args”数组主要是用来接收用户输入参数的
 */
public class ArrayDemo05 {
    //这个方法程序员负责写出来,JVM负责调用。JVM调用的时候一定会传一个String数组过来
    public static void main(String[] args) {
        //JVM默认传递过来的这个数组的长度:默认0
        //通过测试得出args不是null。不是空引用
        System.out.println("JVM给传递过来的String数组的长度是:" + args.length);
        for (int i = 0; i < args.length; i++){
            System.out.println(args[i]);
        }
    }
}

输出结果:
JVM给传递过来的String数组的长度是:0
代码演示8:

//模拟一个系统,假设这个系统要使用,必须输入用户名和密码
public class ArrayDemo06 {
    public static void main(String[] args) {
        if (args.length != 2){
            System.out.println("使用该系统时必须提供用户名和密码,例如:张三 123");
            return;
        }
        //取出用户名
        String usename = args[0];
        //取出密码
        String password = args[1];
        //假设用户名为admin,密码为123表示登录成功。其他一律失败。
        if ("admin".equals(usename) && "123".equals(password)) {
            System.out.println("登陆成功,欢迎使用");
        }else{
            System.out.println("登录失败,用户名不存在或者密码错误");
        }
    }
}

输出结果:
登陆成功,欢迎使用

注意:必须先输入admin 123,才会登录成功。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值