3.31.List,Set,Map是否继承自Collection接口?
参考答案:
List,Set继承自Collection接口,而Map没有继承自Collection接口.
3.32.List底层是怎么实现的?双向链表和数组的区别?
参考答案:
在Java中List是一个接口,继承于Collection接口,并定义了添加元素,删除元素,取出元素等对集合操作的抽象方法.
双向链表和数组区别为:
1.数组必须事先定义固定的长度(元素个数),不能适应数据动态地增减的情况.当数据增加时,可能超出原先定义的元素个数;当数据减少时,造成内存浪费;数据可以根据下标直接存取;
2.链表动态的进行存储分配,可以适应数据动态的增减的情况,且可以方便的插入,删除数据项;而数组中插入,删除数据项时,需要移动其它数据项,非常繁琐.
3.33.说出ArrayList,Vector,LinkedList的存储性能和特性
参考答案:
ArrayList和Vector都是使用数组方式存储数据,此数组元素大于实际存储的数据以便增加和插入元素,它们都允许直接按序号索引元素,但是插入元素涉及数组元素移动等内存操作,所以索引数据快而插入数据慢,Vector由于使用了Synchronized方法(线程安全),通常性能上较ArrayList差,而LinkedList使用双向链表实现存储,按序号索引数据需要进行向前或向后遍历,但是插入数据时只需要记录本项的前后项即可,所以插入速度较快.
3.34.请通过一次循环,清除掉一个ArrayList中的每个元素
参考答案:
public static void main(String[] args){
ArrayList<String> list = new ArrayList<String>();
list.add("a");
list.add("b");
list.add("c");
list.add("d");
list.add("e");
list.add("f");
list.add("g");
for(int i = list.size() - 1; i >= 0; i--){
list.remove(i);
}
System.out.println(list);
}
3.35.设计一个程序基于Map泛型完成10个英文单词的翻译
参考答案:
public static void main(String[] args){
Map<String,String> map = new HashMap<String,String>();
map.put("January","一月");
map.put("February","二月");
map.put("March","三月");
map.put("April","四月");
map.put("May","五月");
map.put("June","六月");
map.put("July","七月");
map.put("August","八月");
map.put("September","九月");
map.put("October","十月");
String str = "September";
if(map.containsKey(Str)){
System.out.println(map.get(str));
} else {
System.out.println("查无此词");
}
}
3.36.Set里的元素是不能重复的,那么用什么方法来区分重复与否呢?是用==还是equals()?它们有何区别?
参考答案:
Set里的元素是不能重复的,使用equals方法和hashCode方法来区分重复与否.覆盖equals方法,hashCode方法用来判断两个对象是否为同一对象,而”==”判断地址是否相等,用来决定引用值是否指向同一对象.
3.37.编写一个list集合,存储通讯录,(同学姓名和电话)并输出通讯录
参考答案:
public class Record implements Comparable<Record>{
private int id;
private String name;
private String phone;
public Record(){
}
public Record(String anme ,String phone){
this.name = name;
this.phone = phone;
}
public int getId(){
return id;
}
public void setId(int id){
this.id = id;
}
public String getName(){
return name;
}
public void setName(String name){
this.name = name;
}
public String getPhone(){
return phone;
}
public void setPhone(String phone){
this.phone = phone;
}
@Override
public String toString(){
return name + ":" + phone + " ";
}
@Override
public int compareTo(Record o){
return Collar.getInstance(Locale.CHINESE).compare(this.name,o.getName());
}
}
public class CommunicationRecord{
private int size = 0;
private List<Record> list = new ArrayList<Record>();
public CommunicationRecord(){
}
public int getSize(){
return size;
}
public void add(Record r){
if(r != null){
list.add(r);
Collections.sort(list);
}
}
@Override
public String toString(){
return list.toString();
}
public static void main(String[] args){
CommunicationRecord c = new CommunicationRecord();
c.add(new Record("张三","111"));
c.add(new Record("李四","222"));
c.add(new Record("王五","333"));
c.add(new Record("赵六","444"));
System.out.println(c);
}
}
3.38.有两个List,写一个方法要求合并这两个集合,不能有重复的,不能用集合的sort等方法,而且要求中间的数字最大,两边逐渐减小.
参考答案:
public static void main(String[] args){
List<Integer> list1 = new ArrayList<Integer>();
list1.add(4);
list1.add(4);
list1.add(5);
list1.add(1);
list1.add(7);
list1.add(9);
List<Integer> list2 = new ArrayList<Integer>();
list2.add(4);
list2.add(8);
list2.add(5);
list2.add(11);
list2.add(17);
list2.add(9);
list2.add(2);
list2.add(3);
list2.add(19);
TreeSet<Integer> set = new TreeSet<Integer>(list1);
set.addAll(list2);
List<Integer> ss = new ArrayList<Integer>(set);
List<Integer> list = new ArrayList<Integer>();
for(int i = 0; i < ss.size(); i = i + 2){
list.add(ss.get(i));
}
for(int i = (ss.size()) / 2 * 2 - 1; i > 0; i = i - 2){
list.add(ss.get(i));
}
System.out.println(list);
}
3.39.将文件夹a(包括其下所有子文件夹和文件)复制到文件夹b下.要求:使用10个线程同时进行,每一个线程独立处理一个文件.
参考答案:
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class Q039{
MyThread[] threads = new MyThread[10];
public int n = 0;
public Q039(){
for(int i = 0; i < threads.length; i++){
threads[i] = new MyThread();
}
}
public static void main(String[] args){
new Q039().copyDirectiory(new File("d:\\a",new File("d:\\b"));
}
public void copyDirectiory(File sourceDir,File targetDir) throws Exception{
if(!targetDir.exists()){
targetDir.mkdirs();
}
File[] file = sourceDir.listFiles();
for(int i = 0; i < file.length; i++){
if(file[i].isFile()){
File targetFile = new File(targetDir.getAbsolutePath() + File.separatpr + file[i].getName());
MyThread t = threads[n++ % 10];
t.set(file[i],targetFile);
t.start();
t.join();
threads[n % 10] = new MyThread();
}
if(file[i].isDirectory()){
String dir2 = targetDir.getAbsolutePath() + File.separator + file[i].getName();
copyDirectiory(file[i],new File(dir2));
}
}
}
}
class MyThread extends Thread{
private File src;
private File desc;
public MyThread(){
}
public void set(File src,File desc){
this.src = src;
this.desc = desc;
}
@Override
public void run(){
try{
copyFile(src,desc);
} catch(IOException e){
e.printStackTrace();
}
}
public static void copyFile(File src,File desc) throws IOExeption{
if(!desc.exists()){
desc.createNewFile();
}
BufferedInputStream bis = null;
BufferedOutputStream bos = null;
try{
FileInputStream fis = new FileInputStream(src);
FileOutputStream fos = new FileOutputStream(desc);
bis = new BufferedInputStream(fis);
bos = new BufferedOutputStream(fos);
int b = -1;
while((b = bis.read()) != -1){
bos.write(b);
}
} finally {
if(bis != null){
bis.close();
}
if(bos != null){
bos.flush();
bos.close();
}
}
}
}
3.40.请说明什么是线程安全
参考答案:
如果你的代码所在的进程中有多个线程在同时运行,而这些线程可能会同时运行这段代码;如果每次运行结果和单线程运行的结果是一样的,而且其他的变量的值也和预期的是一样的,就是线程安全的.或者说:一个类或者程序锁提供的接口对于线程来说是原子操作或者多个线程之间的切换不会导致该接口的执行结果存在二义性,也就是说我们不用考虑同步的问题.
线程安全问题都是由全局变量及静态变量引起的.若每个线程中对全局变量,静态变量只有读操作,而无写操作,一般来说,这个全局变量是线程安全的;若有多个线程同时执行写操作,一般都需要考虑线程同步,否则的话就可能影响线程安全.