Java第十六天

Java第十六天,第1张

续昨天----------------------
一. 补充:equals()方法:
注意:重写equals方法的时候要彻底。

//equals方法重写要彻底
public class Main {
    public static void main(String[] args) {
        User u1=new User("张三",new Address("烟台","普照路","11111"));
        User u2=new User("张三",new Address("烟台","普照路","11111"));
        System.out.println(u1.equals(u2));//true

   User u3=new User("张三",new Address("烟台","金辉路","11111"));
        System.out.println(u1.equals(u3));//false
    }
}
class User{
    //用户名
    String name;//保存的是地址(0x1234)
    //用户的地址
    Address addr;//保存的是地址(0x5210)
    public User(){}
    public User(String name,Address addr){
        this.name=name;
        this.addr=addr;
    }
    //重写equals方法
    //重写规则:当一个用户的用户名和家庭住址都相同,表示同一个用户
    //修改前:equals判断的是User对象和User对象是否相等
    public boolean equals(Object o) {
        //用户名和用户名相同,住址和住址相同的时候,认定为同一个用户
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        User user = (User) o;
        return this.name.equals(user.name) && this.addr.equals(user.addr);
    }
}
class Address{
    String city;
    String street;
    String zipcode;
    public Address(){}
    public Address(String city,String street,String zipcode){
        this.city=city;
        this.street=street;
        this.zipcode=zipcode;
    }
    //重写equals
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Address address = (Address) o;
        return this.city.equals(address.city) && this.street.equals(address.street) && this.zipcode.equals(address.zipcode);
    }
}

二. hashCode方法:
在Object中的hashCode方法是怎样的?
public native int hashCode();
这个方法不是抽象方法,带有native关键字,底层调用C++程序。
hashCode()方法返回的是哈希码:
实际上就是一个Java对象的内存地址,经过哈希算法,得出的一个值。
所以hashCode()方法的执行结果可以等同看作一个java对象的内存地址。

public class Main {
    public static void main(String[] args) {
        Object o=new Object();
        int hashCodeValue=o.hashCode();
        //对象内存地址经过哈希算法转换的一个数字。可以等同看作内存地址。
        System.out.println(hashCodeValue);//2003749087
        Myclass mc=new Myclass();
        System.out.println(mc.hashCode());//990368553
        Myclass mc2=new Myclass();
        System.out.println(mc2.hashCode());//1096979270
    }
}
	class Myclass{

}

三. 匿名内部类:
1.什么是内部类?
内部类:在类的内部又定义了一个新的类。被称为内部类。
2.内部类的分类:
静态内部类:类似于静态变量
实例内部类:类似于实例变量
局部内部类:类似于局部变量
3.使用内部类编写的代码,可读性很差。能不用尽量不用。
4.匿名内部类是局部内部类的一种。因为这个类没有名字而得名,叫做匿名内部类。
5.学习匿名内部类主要是为了能有阅读理解别人的代码
并不代表以后都要这么写。因为匿名内部类有两个缺点:
缺点1:太复杂,太乱,可读性太差。
缺点2:类没有名字,以后想重复使用,不能用。

public class Main {
    //静态变量
    static String country;
    //该类在类的内部,所以称为内部类
    //由于前面有static,所以称为"静态内部类"
    static class Inner1{
    }

   //实例变量
    int age;
    //该类在类的内部,所以称为内部类
    //没有static,称为"实例内部类"
    class  Inner2{
    }

   //方法
    public void doSome(){
        //局部变量
        int i=100;
        //该类在类的内部,所以称为内部类
        //局部内部类
        class Inner3{
        }
    }
    public void doOther(){
        //doSome()方法中的局部内部类Inner3,在doOther()中无法使用
    }
    //main方法:入口
    public static void main(String[] args) {
        //调用MyMath中的mySum方法。
        MyMath mm=new MyMath();
        /*
        Copute c=new ComputeImpl();
        mm.MySum(c,100,200);
         */
        //合并(这样写代码,表示这个类名是有的。类名是ComputeImpl)
        //mm.mySum(new ComputeImpl(),100,200);
        //使用匿名内部类,表示这个CompuImpl这个类没名字了。
        //这里表面看上去好像是接口可以直接new了,实际上并不是接口可以new了。
        //后面的{}代表了对接口的实现。
        //不建议使用匿名内部类,为什么?
        //因为一个类没有名字,没有办法重新使用。另外代码太乱,可读性太差。
        mm.mySum(new Compute(){
            public int sum(int a, int b) {
                return a+b;
            }
        },100,200);
    }
}

//负责计算的接口
interface Compute{
    //抽象方法
    int sum(int a,int b);
}

//你自动会在这里编写一个Compute接口的实现类
/*class ComputeImpl implements Compute{
    //对方法的实现
    public int sum(int a,int b){
        return a+b;
    }
}
*/

//数学类
class MyMath{
    //数学求和方法
    public void mySum(Compute c,int x,int y){
        int val=c.sum(x,y);
        System.out.println(x+"+"+y+"="+val);
    }
}

四. 数组:
1.数组这种数据结构的优点和缺点是什么?
优点:查询/查找/检索某个下标上的元素时效率极高。可以说是查询效率最高的一个数据结构。
为什么检索效率高?
1)每一个元素的内存地址在空间存储上是连续的。
2)每一个元素类型相同,所以占用空间大小一样。
3)知道第一个元素的内存地址,知道每一个元素占用的空间的大小,又知道下标,所以通过一个数学表达式就可以计算出某个下标上元素的内存地址。直接通过内存地址定位元素,所以数组的检索效率是最高点。
缺点:
1)由于为了保证数组中每个元素的内存地址连续,所以在数组上随机删除或者增加元素的时候,效率较低,因为随机增删元素会涉及到后面元素统一向前或者向后位移的 *** 作。
2)数组不能存储大数据量,为什么?
因为很难在内存空间上找到一块特别大的连续的内存空间。
注意:对于数组中最后一给元素的增删,是没有效率影响的。

2.一维数组初始化模式:
1)静态初始化模式:
int[] a={1,2,3};
2)动态初始化模式:
int[] a=new int[3];

3.什么采用静态初始化方式,什么时候采用动态初始化方式?
1)当你创建数组的时候,确定数组中存储哪些具体的元素时,采用静态初始化方式。
2)当你创建数组的时候,不确定将来数组中存储哪些数据,你可以采用动态初始化的方式,预先分配内存空间。

4.数组拷贝:
public static native void arraycopy(Object src, int srcPos,
Object dest, int destPos,
int length);
五个参数:第1个为源数组,第2个为源数组拷贝的起始位置,第3个为目标数组,第4个参数为拷贝到目标数组的下标位置,第5个为拷贝的长度

public class ArrestTest01 {
    public static void main(String[] args) {
        //拷贝源(从这个数组中拷贝)
        int[] a={1,2,3};
        //拷贝目标(拷贝到这个目标数组上)
        int[] b=new int[5];
        //调用JDK System类中的arraycopy方法,来实现数组的拷贝
        //System.arraycopy(a,1,b,2,2);
        //遍历目标数组
        /*for(int i=0;i
        System.arraycopy(a,0,b,0,a.length);
        for (int i = 0; i < b.length; i++) {
            System.out.println(b[i]);//1 2 3 0 0
        }
        Object[] obj=new Object[3];
        Object[] newobj=new Object[5];
        System.arraycopy(obj,0,newobj,0,obj.length);
        for (int i = 0; i < newobj.length; i++) {
            System.out.println(newobj[i]);
        }
    }
}

5.二维数组的初始化:
1)静态初始化:

int[][] array={
		 {1,2,3,4},
		 {99,54,21},
		 {56,42,12}
		};

2)动态初始化:

int[][] array=new array[3][4];

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/langs/733754.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-04-27
下一篇 2022-04-27

发表评论

登录后才能评论

评论列表(0条)

保存