java基础1

1)重写equals方法的时候为什么需要重写hashcode?

 

Java的object中equals的实现:

public boolean equals(Object obj) {
        return (this == obj);
    }

可以看到是用来比较两个对象的内存地址是否相等。

hashCode方法是本地方法,用于计算出对象的一个散列值,用于判断在集合中对象是否重复的关键。

在源码注解中大致讲述看:当我们将equals方法重写后有必要将hashCode方法也重写,这样做才能保证不违背hashCode方法中“相同对象必须有相同哈希值”的约定。

作者定义hashCode:将对象的地址值映射为integer类型的哈希值。

  1. 一个对象多次调用它的hashCode方法,应当返回相同的integer(哈希值)。
  2. 两个对象如果通过equals方法判定为相等,那么就应当返回相同integer。
  3. 两个地址值不相等的对象调用hashCode方法不要求返回不相等的integer,但是要求拥有两个不相等integer的对象必须是不同对象。

总的来说:

  1. 相同的对象必然导致相同的哈希值。
  2. 不同的哈希值必然是由不同对象导致的。

在String源码中比较两个对象除了在两个对象的内存地址相等的时候返回true,还会在比较其对应的字符都相等的时候也返回true。所以现在可以得到“因为必须保证重写后的equals方法认定相同的两个对象拥有相同的哈希值”。同时我们顺便得出了一个结论:“hashCode方法的重写原则就是保证equals方法认定为相同的两个对象拥有相同的哈希值”。

同时我们从HashMap中分析(key对象必须重写equals和hashCode)

  1. 无论是 put 还是 get 的时候,都需要得到key的哈希值,去定位key的数组下标;
  2. 在 get 的时候,需要调用equals方法比较是否有相等的key存储过。
User user1=new User("name");
User user2=new User("name");
HashMap<User, String> hashmap=new HashMap<User,String>();
hashmap.put(user1, "value1");
String str=hashmap.get(user2);
System.out.println("输出结果:"+str);//null

上面的例子都未重写equals,所以在查找user2的时候使用的object的equals,比较的是地址,而user1和user2的地址肯定不同,所以找不到。(即使重写了equals而没有重写hashCode也不一定能找的,应为他们的地址不同所以找到的数组下标也不一定相同

2)八种基本类型

整型:byte(8bit)short(16bit)int(32bit)long(64bit)

浮点型:float(32bit)double(64bit)

字符型:char(2字节,16bit)

布尔型:boolean(为true和false,默认值为false)

3)键盘输入(脑抽插播)

import java.util.Scanner;

public class Main {
    public static void main(String[] args){
        Scanner sc = new Scanner(System.in);
        String name = sc.nextLine();
        int age = sc.nextInt();
        float f = sc.nextFloat();
    }
}

4)String底层的数组使用的是final修饰,即如 str1+str2是new了一个String

可以使用stringBuild和stringBuffer的

《Think in Java》中,描述

       HashTable和HashMap区别一样,就是因为HashTable支持线程同步、保证线程安全而导致的性能下降。

  HashTable是线程安全的,很多方法都是synchronized方法。

  HashMap不是线程安全的,但在单线程程序中的性能比HashTable要高。

而现在StringBuffer和StringBuilder类的区别也在于此,StringBuilder类不是线程安全的,但其在单线程中的性能比StringBuffer高。 

5)抽象类和接口的区别

抽象类可以有抽象方法和非抽象方法而接口值能有抽象方法(默认修饰)(但在JDK1.8中接口可以有default和static方法)。

抽象类只能单继承(extends),而接口可以多实现(implements)。

抽象类中的成员可以是private、默认、protected、public的,而接口中的成员全都是public的。

接口只能由static final变量,而抽象类可以有普通变量(因为防止多实现不统一的改变变量,而抽象类是单继承的所以没问题)。

6)普通类和抽象类的区别

抽象类不能被实例化。

抽象类中抽象方法不需要实现。

(含有抽象方法的类必须声明为抽象类abstract class 类名,接口inteface类名)。

7)访问修饰符

public《-protected《-default《-private

1234      123             12            1

1其他包 2当前包 3子类 4当前类

8)自动装箱和自动拆箱

//自动装箱
Integer total = 99;//调用valueOf()

//自动拆箱
int totalprim = total;//调用intValue,对应别的是xxxValue()

è¿éåå¾çæè¿°

9)&与&&

&&之所以称为短路运算,是因为左边为false时右边直接跳过了返回false,

if(x==33 & ++y>0) y会增长,if(x==33 && ++y>0)不会增长,(&&使用时需要注意顺序,比如比较为null和空字符串时)

&还可以用作位运算符,只有对应的两个二进位都为1时,结果位才为1。

10)JDK、JRE、JVM

JDK是java开发工具包( JDK包含了JRE,同时还包括java源码的编译器javac、监控工具jconsole、分析工具jvisualvm等)

JRE是java运行时环境(用户只需要有jre即可运行程序),java虚拟机(JVM),java基础类库

JVM Java虚拟机,加载.class并运行.class

11)final和static

static表示静态或全局,被修饰的属性和方法属于类,可以用类名.静态属性 / 方法名 访问

static属性:静态变量或者叫全局变量,类变量,被修饰的属性和方法属于类,可以用类名.【静态属性 |方法名】 访问

static 修饰的代码块表示静态代码块,当 Java 虚拟机(JVM)加载类时,就会执行该代码块,只会被执行一次(单例模式可以使用

static方法必须被实现不能是抽象的,而且不能被重写

static不能以任何方式调用this和super和非静态方法,因为在类加载时,对象未初始化前已经把类的static加载到了jvm的方法区(此时如果没被final则基本数据类型会被赋值为默认值,0,false。。。,特别的,如static final int  init = 100,则会被赋值为100),所以不知道非静态方法

 

final修饰属性:基本数据类型-值不能改变,对象-引用地址不能变但是对象内容课可以改变

final修饰方法:方法不能被重写

final修饰类:类不能被继承,final 类中的方法默认是 final 的

 

结!

不写了困了,睡觉前刷一题简单题:

题目描述

地上有一个m行和n列的方格。一个机器人从坐标0,0的格子开始移动,每一次只能向左,右,上,下四个方向移动一格,但是不能进入行坐标和列坐标的数位之和大于k的格子。 例如,当k为18时,机器人能够进入方格(35,37),因为3+5+3+7 = 18。但是,它不能进入方格(35,38),因为3+5+3+8 = 19。请问该机器人能够达到多少个格子?

import java.util.LinkedList;
import java.util.Queue;
class Solution {
    public int movingCount(int threshold, int rows, int cols)
    {   if(threshold < 0)
            return 0;
        int[] dp = new int[(1+rows)*(1+cols)];
        dp[0] = 1;
        int[][] kunsile = {{1,0},{-1,0},{0,1},{0,-1}};
        Queue<Integer> queue = new LinkedList<Integer>();
        queue.add(0);
        int sum = 1;
        int w;
        while(queue.peek() != null){
            w = queue.poll();
            int l = w/cols;
            int r = w%cols;
            for(int i = 0; i < kunsile.length; i++){
                int ll = l + kunsile[i][0];
                int rr = r + kunsile[i][1];
                if(ll<0 || rows <= ll || rr < 0 || cols <= rr){
                    continue;
                }
                if(dfs(ll,rr,threshold) && dp[ll*cols+rr]==0){
                    dp[ll*cols+rr] = 1;
                    sum++;
                    queue.add(ll*cols+rr);
                }
            }
        }
        return sum;
    }
    public boolean dfs(int ll, int rr, int threshold){
        int sum = 0;
        while(ll != 0){
            sum += ll%10;
            ll/=10;
        }
        while(rr != 0){
            sum += rr%10;
            rr/=10;
        }
        return sum > threshold ? false :true;
    }
};

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值