闲谈莫论人非!!!
今日整理记录的内容
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设备。
学习心得:观看资料—》思考问题—》实验检验—》整理记录 = 有思想的大牛!