这次是第三期Java经典知识点以及面试题了,希望能给广大面试的童鞋提供帮助哈!
1.试比较String,StringBuffer,StringBuilder三者间的区别。
①:String的值不可变,每次对String操作都会生成新的String对象,这样会浪费内存空间,而StringBuffer和StringBuilder的值能多次修改,并且不会产生新的对象;
②:StringBuilder执行速度快,但线程不安全;StringBuffer执行速度慢,但线程安全;
可参照这篇博客查看具体的区别以及细节,这里不作过多的解释,链接为https://blog.youkuaiyun.com/u011702479/article/details/82262823。
下面分别对StringBuffer以及StringBuilder分别写一个Demo,代码如下:
public class StringBufferDemo {
public static void main(String[] args) {
//内容可以改变的字符串,相比String节省开销
StringBuffer sb = new StringBuffer();
//初始容量默认16字符
StringBuffer sb1 = new StringBuffer(20);
System.out.println(sb.capacity());//16 初始容量
System.out.println(sb1.capacity());//20
//使用StringBuffer和String显示0-9
for(int i=0;i<10;i++) {
sb1.append(i);
}
System.out.println(sb1);
//反转
System.out.println(sb1.reverse());
String str = new String();
for(int i=0;i<10;i++) {
str += i;
}
System.out.println(str);
String str2 = new String();
for(int i=9;i>=0;i--) {
str2+=str.charAt(i);
}
System.out.println(str2);
//希望显示¥6,577.55(按银行方式显示)
double sal = 6577.55;
StringBuffer sb2 = new StringBuffer("6577.55").insert(0, '¥');
sb2.insert(2, ',');
System.out.println(sb2);
}
}
StringBuilder的Demo代码如下:
public class StringBuilderDemo {
public static void main(String[] args) {
//如果项目与线程相关,请使用StringBuffer
StringBuilder sb = new StringBuilder();
sb.append("今天星期四");
sb.insert(4,"hello");
System.out.println(sb);
}
}
这里String也写一个简单的Demo吧,代码如下:
public class StringDemo {
public static void main(String[] args) {
String str = "haha1";
String str2 = str;
System.out.println(str == str2);//true
str2 = "haha1";
System.out.println(str == str2);//true
System.out.println(str2.charAt(3));//a(下标从0开始)
String str3 = "HaHA1";
System.out.println(str2.equalsIgnoreCase(str3));//true
System.out.println(str2.substring(0,2));//ha
String[] strs = str2.split("a");//h,h,1
for(String s :strs) {
System.out.println(s+" ");//"h","h","1"
}
System.out.println();
System.out.println("返回a字母出现的下标:"+str2.indexOf('a'));//1
String strInfo = "你好";
try {
strInfo = new String(strInfo.getBytes("ISO-8859-1"),"utf-8");
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(strInfo);
}
}
2.请比较ArrayList和LinkedList的区别。
①:ArrayList实现了基于动态数组的数据结构,而LinkedList实现了基于链表的数据结构;
②:对于随机的访问或者查询,比如get和set,ArrayList要优于LinkedList,因为LinkedList要移动指针;
③:对于中间元素的添加或者删除操作,比如add和remove,LinkedList要优于ArrayList,因为ArrayList要移动数据。
详情可参照博客链接https://www.cnblogs.com/Jacck/p/8034900.html。
下面写一个小的例子来更加深刻的认识两个不同的数据结构,代码如下:
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
/**
* List应用
* 线性存储
* @author autumn_leaf
*
*/
public class ListDemo {
/**
* List有序集合,按位置从0开始存储,根据下标读取
* @param args
*/
public static void main(String[] args) {
List list = new ArrayList<>();
list.add("one");
list.add("two");
list.add(2,"three");
System.out.println(list);//[one,two,three]
//在集合中如何获取指定位置的内容
System.out.println(list.get(2));//three
//找到指定对象的下标
System.out.println(list.indexOf("two"));//1
List list2 = new ArrayList<>(3);//设置初始容量为3,默认为10
//LinkedList 操作集合中的元素 方便进行队列处理
LinkedList llist = new LinkedList<>();
llist.add("one");
llist.add("two");
System.out.println(llist);//[one,two]
llist.addFirst("zero");
llist.removeLast();//移除最后一个
System.out.println(llist);//[zero,one]
//两者区别:LinkedList功能更多,适用于插入和操作集合
//ArrayList 适用于查询的场景 线性存储
}
}
运行结果如下:
[one, two, three]
three
1
[one, two]
[zero, one]
3.请比较List,Set以及Map三者之间的区别。
①:List和Set都是实现了Collection接口,而Map不是Collection的子接口或者实现类,Map是一个接口;
②:List是一个有序容器,可以允许重复的对象,可以插入多个null元素;Set是一个无序容器,不允许重复的对象(值唯一),只允许一个null值;而Map以键值对形式进行存储,可能有相同的值对象但键对象必须唯一,可以拥有多个null值但最多只能有一个null键;
详情可参考博客链接https://www.cnblogs.com/IvesHe/p/6108933.html。
下面写几个小的例子来更加深刻的认识各自的作用,SetDemo如下:
import java.util.Date;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.HashSet;
import java.util.TreeSet;
public class SetDemo {
/**
* 上层接口是Collection,set集合是一种无序集合,
* 存储内容完全不同,对象要求地址不同
* 存储内容完全不同,并且无序时,选用Set集合
* @param args
*/
public static void main(String[] args) {
//HashSet 散列存取
HashSet s = new HashSet<String>();
s.add("chen");
s.add("liu");
s.add(1);//这里的1并不是int类型,而是转换后的内容
s.add(new Integer(1));
System.out.println(s);
//其实是按照hashCode的值比较进行存储
System.out.println("chen".hashCode()+" "+new Integer(1).hashCode()+" "+"liu".hashCode());
//TreeSet 按照排序树存储,要求各个元素可以直接比较
TreeSet tree = new TreeSet<>();
tree.add("one");
tree.add(new Integer(1).toString());
tree.add(new Float(4.0F).toString());
System.out.println(tree);
//使用自定义对象作为内容放入集合中
HashSet hs = new HashSet<Student>();
Student s1 = new Student(1001,"chen","男",new Date());
hs.add(s1);
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
try {
hs.add(new Student(1002,"zhou","女",sdf.parse("2000-01-01")));
} catch (ParseException e) {
e.printStackTrace();
}
hs.add(3);
hs.remove(3);
hs.remove(s1);
System.out.println(hs);
}
}
运行结果如下:
[chen, 1, liu]
3052494 1 107160
[1, 4.0, one]
[Student [id=1002, name=zhou, sex=女, birth=Sat Jan 01 00:00:00 CST 2000]]
MapDemo代码如下:
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Map;
import java.util.TreeMap;
public class MapDemo {
public static void main(String[] args) {
//HashMap TreeMap HashTable
Map<String,String> hmap = new HashMap<String,String>();
hmap.put("a", "chen");
hmap.put("b", "liu");
hmap.put("c", "zhou");
hmap.put("d", null);
hmap.put(null, null);
hmap.put("a", "a");//键名相同,值进行覆盖
System.out.println(hmap);
Map<String,String> htable = new Hashtable<String,String>();
//注意,HashMap线程不安全,Hashtable线程安全,synchronized关键字加在方法上
//Hashtable不允许录入null,HashMap可以录入null
//htable.put(null, null);
//System.out.println(htable);
// synchronized(htable) {
//
// }
//使用TreeMap有序存储
Map<String,String> tmap = new TreeMap<String,String>();
tmap.put("a", "chen");
tmap.put("b", "liu");
tmap.put("c", "zhou");
//tmap.put(null, null);//key不能为空
tmap.put("d", null);
System.out.println(tmap);
System.out.println(tmap.get("b"));//liu
}
}
运行结果如下:
{null=null, a=a, b=liu, c=zhou, d=null}
{a=chen, b=liu, c=zhou, d=null}
liu
4.试比较HashMap,Hashtable,TreeMap的区别。
①:这三个都对Map接口进行了实现;
②:HashMap线程不安全,但执行速度快;它允许key值出现一次null,value值出现多次null;
③:Hashtable线程安全,但执行速度慢;key和value的值均不允许为null;
④:TreeMap可以排序,默认按照键的自然顺序进行升序排序。
5.请比较Collection与Collections的区别。
Collection是集合类的上级接口,其中Map和Set都实现了Collection接口,提供了通用的接口方法;而Collections是一个工具类,提供了一系列的静态方法实现对集合的搜索、排序等操作,关于具体的区别以及例子可以参照这篇博客,链接为https://blog.youkuaiyun.com/ETEmonster/article/details/94735940,关于Collections的使用,一个简易的Demo代码如下:
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class CollectionsDemo {
public static void main(String[] args) {
//Collection是集合,Collections是为操作集合提供的一个工具类
List list = new ArrayList<>();
list.add("apple");
list.add("pear");
list.add("banana");
list.add("orange");
list.add("grape");
String max = (String) Collections.max(list);
String min = (String) Collections.min(list);
System.out.println(max);
System.out.println(min);
Collections.sort(list);
System.out.println("排序后:"+list);
}
}
运行结果如下:
pear
apple
排序后:[apple, banana, grape, orange, pear]
好了,本期就讲到这里了,我们下一期再见!