续昨天----------------------
一. 补充: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];
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)