Java学习笔记五

闲谈莫论人非!!!

今日整理记录的内容
1.浅谈API
2.字符串常量
3.哈希列表
4.Timer
5.小知识点

一、浅谈API
API(Application Programming Interface): 应用程序接口。一个东西能做什么事情,把能做的事情的名字,告诉外面,外面只需要通过事情的名字就能实现这件事情。
解释:

//这是一个汽车类
public class CarAPITest {

    /*接下来我们定义汽车类的API*/

    public void run(){
        System.out.println("汽车能跑");
    }

    public void stop(){
        System.out.println("汽车能停止");
    }

    public void accelerate(){
        System.out.println("汽车能加速");
    }

我们在这里写了一个汽车类,这时候我们只需将汽车能干的事情(有哪些对外暴露的方法),的名字整理成一个文档,这个文档就是汽车这个类的API,

汽车类的API文档
     void run();  ------调用这个方法,汽车启动并跑起来。
    void stop(); ------调用这个方法,汽车停止。
    void accelerate(); -------调用这个方法,汽车加速。

我们平常说的Java API,就是Java这个事物能做哪些事情,并把能做的事情的名字整理成一个文档,供外界使用。

二、字符串常量
字符串常量(如“Hello”):实际上是一种特殊的匿名String对象。如程序中使用了“Hello”字符串常量,就会把它存到内存中,如果程序中再次出现就会先从内存中找。所以多个不同的变量可以指向相同的字符串常量,这样节约了内存。
解释:

public class StringTest {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
            String str1 = "hello";//这里用到了字符串常量“hello” ---①
            String str2 = "hello";//这里又用到了字符串常量“hello” ---②
            String str3 = new String("hello");//注意!!!这里用的不是字符串常量---③
            System.out.println(str1 == str2);
            System.out.println(str1 == str3);
    }
}
输出结果:
true
false

当程序执行到①时,内存会为字符串常量“hello”开辟一块内存区域,并把“hello”放进去,当②处再次用到“hello”时,就会从内存区域拿出之前已经存好的,也就是说str1 和 str2 所指向的内容(地址)相同;而③处不是用的字符串常量,而是通过实例化new的方式创建 字符串内容,虽然都是”hello”,但③处是自己重新开辟一块内存区域,然后把“hello”放进去,所以 str1 和 str3所指向的内容(地址)不同。

三、哈希(HashCode)列表
hashCode: 根据哈希算法得到的值就是哈希值,java中每new出一个Object时都会给这个对象生成一个哈希值存放到总哈希列表中。Java中的hashCode方法就是根据一定的规则将与对象相关的信息(比如对象的存储地址,对象的字段等)映射成一个数值,这个才是哈希值。
通过哈希列表的方式对数据进行存储的优点是查询速度快,查询过程是这样的:先得到对象的哈希值,然后跟据哈希值到哈希列表中找到对应的区域,如果区域中不存在其他对象,则把它存进去;如果存在其他对象,证明这个对象和其他对象的哈希值相同,那么再通过equals()方法挨个和其他对象比较,如果有相同的则认为两个对象一致,就不会再存进去,如果都不同则认为两个对象不一致,就会存进去。
总结一句话:哈希列表就是把哈希值相同equlas()不同的对象存到一个区域,把哈希值不同的对象存到不同的区域。
java中用到的哈希列表存储对象的有:Hashtable、HashMap、HashSet。
解释:
接下来我们通过一个实例代码,来说明Hash… 是通过什么(键还是值还是键和值?)判断两个对象是否相等的;复写equlas()和hashcode()两个方法有什么用?

public class HashTest {

    public static void main(String[] args){
        Hashtable ht1 = new Hashtable();        
        CustomKey1 key1 = new CustomKey1(1,1);
        CustomKey1 key2 = new CustomKey1(1,1);
        ht1.put(key1, "key1");
        ht1.put(key2, "key2");
        System.out.println("ht1总长度:"+ht1.size()+
                " key1的哈希值:"+key1.hashCode()+
                " key2的哈希值:"+key2.hashCode()+
        " key1和key2进行equals()比较:"+key1.equals(key2));

        Hashtable ht2 = new Hashtable();    
        CustomKey2 key3 = new CustomKey2(2, 2);
        CustomKey2 key4 = new CustomKey2(2, 2);
        ht2.put(key3, "key3");
        ht2.put(key4, "key4");
        System.out.println("ht2总长度:"+ht2.size()+
                " key3的哈希值:"+key3.hashCode()+
                " key4的哈希值:"+key4.hashCode()+
                " key3和key4进行equals()比较:"+key3.equals(key4));

    }
}
/*没有复写equlas()和hashcode()方法*/
class CustomKey1{
    private int x;
    private int y;
    public CustomKey1(int x, int y) {
        super();
        this.x = x;
        this.y = y;
    }   
}
/*复写equlas()和hashcode()方法*/
class CustomKey2{
    private int x;
    private int y;
    public CustomKey2(int x, int y) {
        super();
        this.x = x;
        this.y = y;
    }
    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + x;
        result = prime * result + y;
        return result;
    }
    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        CustomKey2 other = (CustomKey2) obj;
        if (x != other.x)
            return false;
        if (y != other.y)
            return false;
        return true;
    }   
}
输出结果:
ht1总长度:2 key1的哈希值:366712642 key2的哈希值:1829164700 key1和key2进行equals()比较:false
ht2总长度:1 key3的哈希值:1025 key4的哈希值:1025 key3和key4进行equals()比较:true

看完了上面的代码和输出结果我们可以得到两条信息:
1.Hash… 是通过比较键对象的equlas()和hashcode()两个方法决定是否对数据进行存储的。
2.我们可以通过重写equlas()和hashcode()两个方法来改变两个对象是否相等的条件。

四、Timer
1.Timer可以定时周期性执行TimerTask的run方法。
2.TimerTask的run方法使用完如果不立即调用TImer的cancle()方法,就会过一段时间线程才被销毁。这一点和Thread有区别,Thread执行完Runnable的run()方法后线程就会立即被销毁。
解释:
在这里我贴出我的测试代码,如果你想测试上面的两条也可以用着段代码

public class TimerTest {

    private static boolean stop = false;

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Timer timer = new Timer();
        TimerTask tt = new TimerTask() {

            @Override
            public void run() {
                // TODO Auto-generated method stub
                System.out.println("执行TimerTask的run()方法");
                stop = true;
            }
        };
        timer.schedule(tt, 1000, 500);
        while(!stop){
            showThreaCount();
        }
        for(int i = 0; i < 10; i++){
            showThreaCount();
        }


//      new Thread(new Runnable() {
//          
//          @Override
//          public void run() {
//              // TODO Auto-generated method stub
//              System.out.println("执行Thread的run()方法");
//              stop = true;
//          }
//      }).start();

    }

    private static void showThreaCount(){
        System.out.println(Thread.activeCount());
    }
}

小的知识点:
1、ArrayList和Vector:ArrayList线程不安全的,Vector是线程安全的。
2、List、Set、Collection三个集合类的区别:Collection是Set和List的父类,Set和 List是Collection的子类。
Colletion中各元素没有指定的顺序,可有重复元素和多个null。
Set中各元素没有指定的顺序,不可有重复元素和最多有一个null(利用哈希列表)
List中各元素有指定的顺序,可有重复元素和多个null。
3、RandomAccessFile类:提供了众多的文件访问方法。最大的特点就是“随机访问”方式。仅限于操作文件,不能访问其他的IO设备。

学习心得:观看资料—》思考问题—》实验检验—》整理记录 = 有思想的大牛!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值