今天看一篇博客里面提到了一些Java新手经常问到的问题。貌似不知道就太low了。有些是自己的回答,有些是参考的原文链接,在此记录一下。
常见问题
一般问题
Java与JavaScript有什么不同
除了名字差不多,其他都不同
Java程序如何转化成.exe文件
我也曾想过要这样装逼。但发现并无卵用。有一些工具可以帮助你将Java程序打包成.exe文件,比如exe4j,之前还用过两个,忘记了,不过劝谏大家别在这个上浪费时间。
String,StringBuilder与toString
[PS:我感觉是不是还差一个StringBuffer]
在Java中如何比较字符串
笼统的说,equals和==都可以,但是,我们看一个例子
public class Main {
public static void main(String[] args) {
new Main().test();
}
public void test(){
String string1 = "123";
String string2 = "123";
String string3 = new String("123");
String string4 = new String(string1);
print("string1"+(string1==string2?"==":"!=")+"string2");
print("string1"+(string1==string3?"==":"!=")+"string3");
print("string1"+(string1==string4?"==":"!=")+"string4");
print("string3"+(string3==string4?"==":"!=")+"string4");
print("string1 "+(string1.equals(string2)?"equals ":"not equals ")+"string2");
print("string1 "+(string1.equals(string3)?"equals ":"not equals ")+"string3");
print("string1 "+(string1.equals(string4)?"equals ":"not equals ")+"string4");
print("string1 "+(string3.equals(string4)?"equals ":"not equals ")+"string4");
}
public void print(String str){
System.out.println(str);
}
}
再看结果:
使用==的时候,只有string1和string2相等。
使用equals的时候,这四个String是相等的。
我们来去看一下equals的源码:
public boolean equals(Object anObject) {
if (this == anObject) { //先判断引用是否相同
return true;
}
if (anObject instanceof String) { //再判断内容是否相同
String anotherString = (String)anObject;
int n = value.length;
if (n == anotherString.value.length) {
char v1[] = value;
char v2[] = anotherString.value;
int i = 0;
while (n-- != 0) { //遍历每一个字符是否相同
if (v1[i] != v2[i])
return false;
i++;
}
return true;
}
}
return false;
}
那么可以看出,==只是判断引用是否相同,equals是判断内容是否相同。
那么我们再来看一个例子:
将上面例子中的test函数稍微更改一下,其他一样不再贴出。
public void test(){
String string1 = "123";
String string2 = "123";
String string3 = new String("123");
String string4 = new String("123");
print("string1"+(string1==string2?"==":"!=")+"string2");
print("string3"+(string3==string4?"==":"!=")+"string4");
print("string1 "+(string1.equals(string2)?"equals ":"not equals ")+"string2");
print("string3 "+(string3.equals(string4)?"equals ":"not equals ")+"string4");
}
结果:
string1和string2引用相同,string3和string4引用不同;
这是为什么呢?
因为这两种初始化字符串的方式不同。string1和string2的方式是通过Java中的字符串池来创建的。当你直接通过”“来创建,Java虚拟机会先去字符串池中寻找是否包含该字符串对象,如果已经包含了,那么就直接返回这个字符串的引用。而如果没有则会新创建一个。
而通过new创建的string是实实在在的创建了一个String对象,而且和字符串池没有关系,即使内容相同也是不同的对象。自然引用也就不一样了。
Java中的StringBuffer和StringBuilder
我再加一个String
String
1,Stirng是对象不是基本数据类型
2,String是final类,不能被继承。是不可变对象,一旦创建,就不能修改它的值。
3,对于已经存在的Stirng对象,修改它的值,就是重新创建一个对象,然后将新值赋予这个对象
StringBuffer
1,一个类似于 String 的字符串缓冲区,对它的修改的不会像String那样重创建对象。
2,使用append()方法修改Stringbuffer的值,使用toString()方法转换为字符串。
Stringbuild
是jdk1.5后用来替换stringBuffer的一个类,大多数时候可以替换StringBuffer。和StringBuffer的区别在于Stringbuild是一个单线程使用的类,不值执行线程同步所以比StringBuffer的速度快,效率高。是线程非安全的。
为什么当我在自己的 Java 项目中打印时得到 SomeType@2f92e0f4?
例子:
public class Main {
public static void main(String[] args) {
Test test = new Test("1");
System.out.print(test);
}
}
public class Test {
private String name ;
public Test(String name) {
this.name = name;
}
}
结果:
这是如何出来的?
System.out.print最终调用的事对象的toString函数,我们在自己自定义的类中没有重写toString函数,所以调用的就是Object的toString函数。
public String toString() {
return getClass().getName() + "@" + Integer.toHexString(hashCode());
}
对就是他,这下明白了吧;
Java 中的字符串常量
就是String
equals 与 hashCode
equals() 和 == 有什么不同
参考上面String时的解答
在 Java 中重写 equals() 和 hashCode() 方法
虽然没有太明白这是什么意思,既然可以重写,怎么重写应该都可以吧,但是按照规矩。(PS:就像是我们规定不能杀人,不还是有杀人犯吗?)按规矩的话:equals函数必须要定义一种相等的关系,这个关系中,自己和自己可能是相等的,和null都不相等,而非上面的情况一般看hashcode。当然你可以不按套路出牌。
hashcode要定义一种该对象与一个int值的对映关系。
Java Platform SE API
使用 nextInt() 后跳过 nextLine()
这个我也不知道,查了一下:
Java中Scanner的nextInt(),next(),nextLine()方法总结
在 Java 中比较日期
有after和before函数
在迭代集合的过程中做高效地删除操作
首先了解一下Java中的集合相关的知识:
java中的容器讲解
然后看一下这个问题和解答:
Iterating through a list, avoiding ConcurrentModificationException when removing in loop
如何排序 Map中的值
使用TreeMap+Comparetor
一个直接利用TreeMap排序的简单例子:
public class Main {
public static void main(String[] args) {
TreeMap<String,Integer> map = new TreeMap<>(new Comparator() {
@Override
public int compare(Object o1, Object o2) {
return String.valueOf(o1).compareTo(String.valueOf(o2));
}
});
map.put("c", 6);
map.put("a",7);
map.put("b",8);
System.out.println(map);
}
}
结果:
另一个方法对外部的map排序,其实也是外部的map重新put到一个TreeMap中进行排序的:
public class Main {
public static void main(String[] args) {
Map<String,Integer> map = new HashMap<>();
ValueComparator bvc = new ValueComparator(map);
TreeMap sorted_map = new TreeMap(bvc);
map.put("A", 99);
map.put("B", 61);
map.put("C", 67);
map.put("D", 66);
System.out.println("unsorted map: " + map);
sorted_map.putAll(map);
System.out.println("results: " + sorted_map);
}
}
class ValueComparator implements Comparator<String> {
Map<String,Integer> base;
public ValueComparator(Map base) {
this.base = base;
}
@Override
public int compare(String o1, String o2) {
if (base.get(o1) >= base.get(o2)) {
return -1;
} else {
return 1;
}
}
}