1207集合框架习题与实践.docx
《1207集合框架习题与实践.docx》由会员分享,可在线阅读,更多相关《1207集合框架习题与实践.docx(17页珍藏版)》请在冰点文库上搜索。
1207集合框架习题与实践
1、Collection框架中实现比较要实现什么接口
comparable/comparator
2、ArrayList和Vector的区别
答:
这两个类都实现了List接口(List接口继承了Collection接口),他们都是有序集合,即存储在这两个集合中的元素的位置都是有顺序的,相当于一种动态的数组,我们以后可以按位置索引号取出某个元素,,并且其中的数据是允许重复的,这是HashSet之类的集合的最大不同处,HashSet之类的集合不可以按索引号去检索其中的元素,也不允许有重复的元素(本来题目问的与hashset没有任何关系,但为了说清楚ArrayList与Vector的功能,我们使用对比方式,更有利于说明问题)。
接着才说ArrayList与Vector的区别,这主要包括两个方面:
.
(1)同步性:
Vector是线程安全的,也就是说是它的方法之间是线程同步的,而ArrayList是线程序不安全的,它的方法之间是线程不同步的。
如果只有一个线程会访问到集合,那最好是使用ArrayList,因为它不考虑线程安全,效率会高些;如果有多个线程会访问到集合,那最好是使用Vector,因为不需要我们自己再去考虑和编写线程安全的代码。
备注:
对于Vector&ArrayList、Hashtable&HashMap,要记住线程安全的问题,记住Vector与Hashtable是旧的,是java一诞生就提供了的,它们是线程安全的,ArrayList与HashMap是java2时才提供的,它们是线程不安全的。
所以,我们讲课时先讲老的。
(2)数据增长:
ArrayList与Vector都有一个初始的容量大小,当存储进它们里面的元素的个数超过了容量时,就需要增加ArrayList与Vector的存储空间,每次要增加存储空间时,不是只增加一个存储单元,而是增加多个存储单元,每次增加的存储单元的个数在内存空间利用与程序效率之间要取得一定的平衡。
Vector默认增长为原来两倍,而ArrayList的增长策略在文档中没有明确规定(从源代码看到的是增长为原来的1.5倍)。
ArrayList与Vector都可以设置初始的空间大小,Vector还可以设置增长的空间大小,而ArrayList没有提供设置增长空间的方法。
总结:
即Vector增长原来的一倍,ArrayList增加原来的0.5倍。
3、HashMap和Hashtable的区别
(条理上还需要整理,也是先说相同点,再说不同点)
HashMap是Hashtable的轻量级实现(非线程安全的实现),他们都完成了Map接口,主要区别在于HashMap允许空(null)键值(key),由于非线程安全,在只有一个线程访问的情况下,效率要高于Hashtable。
HashMap允许将null作为一个entry的key或者value,而Hashtable不允许。
HashMap把Hashtable的contains方法去掉了,改成containsvalue和containsKey。
因为contains方法容易让人引起误解。
Hashtable继承自Dictionary类,而HashMap是Java1.2引进的Mapinterface的一个实现。
最大的不同是,Hashtable的方法是Synchronize的,而HashMap不是,在多个线程访问Hashtable时,不需要自己为它的方法实现同步,而HashMap就必须为之提供外同步。
Hashtable和HashMap采用的hash/rehash算法都大概一样,所以性能不会有很大的差异。
就HashMap与HashTable主要从三方面来说。
一.历史原因:
Hashtable是基于陈旧的Dictionary类的,HashMap是Java1.2引进的Map接口的一个实现
二.同步性:
Hashtable是线程安全的,也就是说是同步的,而HashMap是线程序不安全的,不是同步的
三.值:
只有HashMap可以让你将空值作为一个表的条目的key或value
4、List和Map区别?
一个是存储单列数据的集合,另一个是存储键和值这样的双列数据的集合,List中存储的数据是有顺序,并且允许重复;Map中存储的数据是没有顺序的,其键是不能重复的,它的值是可以有重复的。
5、List,Set,Map是否继承自Collection接口?
List,Set是,Map不是
6、List、Map、Set三个接口,存取元素时,各有什么特点?
首先,List与Set具有相似性,它们都是单列元素的集合,所以,它们有一个功共同的父接口,叫Collection。
Set里面不允许有重复的元素,所谓重复,即不能有两个相等(注意,不是仅仅是相同)的对象,即假设Set集合中有了一个A对象,现在我要向Set集合再存入一个B对象,但B对象与A对象equals相等,则B对象存储不进去,所以,Set集合的add方法有一个boolean的返回值,当集合中没有某个元素,此时add方法可成功加入该元素时,则返回true,当集合含有与某个元素equals相等的元素时,此时add方法无法加入该元素,返回结果为false。
Set取元素时,没法说取第几个,只能以Iterator接口取得所有的元素,再逐一遍历各个元素。
List表示有先后顺序的集合,注意,不是那种按年龄、按大小、按价格之类的排序。
当我们多次调用add(Obje)方法时,每次加入的对象就像火车站买票有排队顺序一样,按先来后到的顺序排序。
有时候,也可以插队,即调用add(intindex,Obje)方法,就可以指定当前对象在集合中的存放位置。
一个对象可以被反复存储进List中,每调用一次add方法,这个对象就被插入进集合中一次,其实,并不是把这个对象本身存储进了集合中,而是在集合中用一个索引变量指向这个对象,当这个对象被add多次时,即相当于集合中有多个索引指向了这个对象,如图x所示。
List除了可以以Iterator接口取得所有的元素,再逐一遍历各个元素之外,还可以调用get(indexi)来明确说明取第几个。
Map与List和Set不同,它是双列的集合,其中有put方法,定义如下:
put(objkey,objvalue),每次存储时,要存储一对key/value,不能存储重复的key,这个重复的规则也是按equals比较相等。
取则可以根据key获得相应的value,即get(Objectkey)返回值为key所对应的value。
另外,也可以获得所有的key的结合,还可以获得所有的value的结合,还可以获得key和value组合成的Map.Entry对象的集合。
List以特定次序来持有元素,可有重复元素。
Set无法拥有重复元素,内部排序。
Map保存key-value值,value可多值。
HashSet按照hashcode值的某种运算方式进行存储,而不是直接按hashCode值的大小进行存储。
例如,"abc"--->78,"def"--->62,"xyz"--->65在hashSet中的存储顺序不是62,65,78,这些问题感谢以前一个叫崔健的学员提出,最后通过查看源代码给他解释清楚,看本次培训学员当中有多少能看懂源码。
LinkedHashSet按插入的顺序存储,那被存储对象的hashcode方法还有什么作用呢?
学员想想!
hashset集合比较两个对象是否相等,首先看hashcode方法是否相等,然后看equals方法是否相等。
new两个Student插入到HashSet中,看HashSet的size,实现hashcode和equals方法后再看size。
同一个对象可以在Vector中加入多次。
往集合里面加元素,相当于集合里用一根绳子连接到了目标对象。
往HashSet中却加不了多次的。
7、说出ArrayList,Vector,LinkedList的存储性能和特性
ArrayList和Vector都是使用数组方式存储数据,此数组元素数大于实际存储的数据以便增加和插入元素,它们都允许直接按序号索引元素,但是插入元素要涉及数组元素移动等内存操作,所以索引数据快而插入数据慢,Vector由于使用了synchronized方法(线程安全),通常性能上较ArrayList差,而LinkedList使用双向链表实现存储,按序号索引数据需要进行前向或后向遍历,但是插入数据时只需要记录本项的前后项即可,所以插入速度较快。
LinkedList也是线程不安全的,LinkedList提供了一些方法,使得LinkedList可以被当作堆栈和队列来使用。
8、Collection和Collections的区别。
Collection是集合类的上级接口,继承与他的接口主要有Set和List.
Collections是针对集合类的一个帮助类,他提供一系列静态方法实现对各种集合的搜索、排序、线程安全化等操作。
9、Set里的元素是不能重复的,那么用什么方法来区分重复与否呢?
是用==还是equals()?
它们有何区别?
Set里的元素是不能重复的,元素重复与否是使用equals()方法进行判断的。
equals()和==方法决定引用值是否指向同一对象equals()在类中被覆盖,为的是当两个分离的对象的内容和类型相配的话,返回真值。
练习1--扫雷小游戏,效果如下图:
1.答案:
【代码1】:
newLinkedList();
【代码2】:
list.add(block[i][j]);
【代码3】:
list.size();
【代码4】:
(Block)list.get(randomIndex);
【代码5】:
list.remove(randomIndex);
2.模板代码
Block.java
publicclassBlock
{Stringname;
intnumber;
booleanboo=false;
publicvoidsetName(Stringname)
{this.name=name;
}
publicvoidsetNumber(intn)
{number=n;
}
publicintgetNumber()
{returnnumber;
}
publicStringgetName()
{returnname;
}
booleanisMine()
{returnboo;
}
publicvoidsetIsMine(booleanboo)
{this.boo=boo;
}
}
LayMines.java
importjava.util.LinkedList;
publicclassLayMines
{publicvoidlayMinesForBlock(Blockblock[][],intmineCount)
{introw=block.length;
intcolumn=block[0].length;
LinkedListlist=【代码1】//创建空链表list
for(inti=0;i{for(intj=0;j{【代码2】//list添加节点,其中的数据为block[i][j]
}
}
while(mineCount>0)
{intsize=【代码3】//list返回节点的个数
intrandomIndex=(int)(Math.random()*size);
Blockb=【代码4】//list返回索引为randomIndex的节点中的数据
b.setName("雷");
b.setIsMine(true);
【代码5】//list删除索引值为randomIndex的节点
mineCount--;
}
for(inti=0;i{for(intj=0;j{if(block[i][j].isMine()){}
else
{intmineNumber=0;
for(intk=Math.max(i-1,0);k<=Math.min(i+1,row-1);k++)
{for(intt=Math.max(j-1,0);t<=Math.min(j+1,column-1);t++)
{if(block[k][t].isMine())
mineNumber++;
}
}
block[i][j].setName(""+mineNumber);
block[i][j].setNumber(mineNumber);
}
}
}
}
}
BlockView.java
importjava.awt.*;
publicclassBlockViewextendsPanel
{LabelblockName;
ButtonblockCover;
CardLayoutcard;
BlockView()
{card=newCardLayout();
setLayout(card);
blockName=newLabel();
blockCover=newButton();
add("cover",blockCover);
add("name",blockName);
}
publicvoidsetName(Stringname)
{blockName.setText(name);
}
publicStringgetName()
{returnblockName.getText();
}
publicvoidseeBlockName()
{card.show(this,"name");
validate();
}
publicvoidseeBlockCover()
{card.show(this,"cover");
validate();
}
publicButtongetBlockCover()
{returnblockCover;
}
}
MineFrame.java
importjava.awt.*;
importjava.awt.event.*;
publicclassMineFrameextendsFrameimplementsActionListener
{ButtonreStart;
Blockblock[][];
BlockViewblockView[][];
LayMineslay;
introw=10,colum=12,mineCount=22;
intcolorSwitch=0;
PanelpCenter,pNorth;
publicMineFrame()
{reStart=newButton("重新开始");
pCenter=newPanel();
pNorth=newPanel();
pNorth.setBackground(Color.cyan);
block=newBlock[row][colum];
for(inti=0;i{for(intj=0;j{block[i][j]=newBlock();
}
}
lay=newLayMines();
lay.layMinesForBlock(block,mineCount);
blockView=newBlockView[row][colum];
pCenter.setLayout(newGridLayout(row,colum));
for(inti=0;i{for(intj=0;j{blockView[i][j]=newBlockView();
blockView[i][j].setName(block[i][j].getName());
pCenter.add(blockView[i][j]);
blockView[i][j].getBlockCover().addActionListener(this);
}
}
reStart.addActionListener(this);
pNorth.add(reStart);
add(pNorth,BorderLayout.NORTH);
add(pCenter,BorderLayout.CENTER);
setSize(200,232);
setVisible(true);
addWindowListener(newWindowAdapter()
{publicvoidwindowClosing(WindowEvente)
{System.exit(0);
}
});
validate();
}
publicvoidactionPerformed(ActionEvente)
{Buttonsource=(Button)e.getSource();
if(source!
=reStart)
{intm=-1,n=-1;
for(inti=0;i{for(intj=0;j{if(source==blockView[i][j].getBlockCover())
{m=i;
n=j;
break;
}
}
}
if(block[m][n].isMine())
{for(inti=0;i{for(intj=0;j{blockView[i][j].getBlockCover().removeActionListener(this);
if(block[i][j].isMine())
blockView[i][j].seeBlockName();
}
}
}
else
{if(block[m][n].getNumber()>0)
blockView[m][n].seeBlockName();
elseif(block[m][n].getNumber()==0)
for(intk=Math.max(m-1,0);k<=Math.min(m+1,row-1);k++)
{for(intt=Math.max(n-1,0);t<=Math.min(n+1,colum-1);t++)
{blockView[k][t].seeBlockName();
}
}
}
}
if(source==reStart)
{for(inti=0;i{for(intj=0;j{block[i][j].setIsMine(false);
}
}
lay.layMinesForBlock(block,mineCount);
for(inti=0;i{for(intj=0;j{blockView[i][j].setName(block[i][j].getName());
blockView[i][j].seeBlockCover();
blockView[i][j].getBlockCover().addActionListener(this);
}
}
}
}
}
MineExample.java
publicclassLayMineMainClass
{publicstaticvoidmain(Stringargs[])
{newMineFrame();
}
}
练习2--使用TreeSet排序,效果如下:
1.答案:
【代码1】:
newTreeSet();
【代码2】:
treeSet.add(stu);
【代码3】:
tree.iterator();
【代码4】:
te.hasNext()
【代码5】:
(Student)te.next();
2.模板代码
Student.java
publicclassStudentimplementsComparable
{Stringname;
intscore;
Student(Stringname,intscore)
{this.name=name;
this.score=score;
}
publicintcompareTo(Objectb)
{Studentst=(Student)b;
intm=this.score-st.score;
if(m!
=0)
returnm;
else
return1;
}
publicintgetScore()
{returnscore;
}
publicStringgetName()
{returnname;
}
}
StudentFrame.java
importjava.awt.*;
importjava.awt.event.*;
importjava.util.*;
publicclassStudentFrameextendsFrameimplementsActionListener
{TextAreashowArea;
TextFieldinputName,inputScore;
Buttonbutton;
TreeSettreeSet;
StudentFrame()
{treeSet=【代码1】//使用无参数构造方法创建treeSet
showArea=newTextArea();
showArea.setFont(newFont("",Font.BOLD,20));
inputName=newTextField(5);
inputScore=newTextField(5);
button=newButton("确定");
button.addActionListener(this);
PanelpNorth=newPanel();
pNorth.add(newLabel("Name:
"));
pNorth.add(inputName);
pNorth.add(newLabel("Score:
"));
pNorth.add(inputScore);
pNorth.add(button);
add(pNorth,BorderLayout.NORTH);
add(showArea,BorderLayout.CENTER);
setSize(3
|
|
|
|
|
|
|
|