是skype电话面试,先行记录下来,总共有两道:
1. 通过栈的操作实现队列的操作:
即 用栈的基本方法push pop 实现 出队和入队的方法
难点在于在不给出提示的情况下,能不能想出使用两个栈来实现队列操作。
(1) 先将stack1 的所有数据pop,然后push至stack2 。
(2) 取出stack2 的顶部元素, 实现出队操作。
(3) 将stack2的所有元素,取出并压入至stack1中,此时可以在stack1中进行入队操作。
2. 如何实现一个map
我们知道,Map<K,V>是一个通用的接口,保存的对象时一个一个的键值对,核心就是如何在内部将键值对进行保存。
看过源码之后可以发现,除了在接口中存在put,get的操作方法,还有一个 内部接口Entry<K,V>(保存键值对)。
jdk中,对Map有一个抽象的实现类abstractMap, 其中有一个内部类SimpleEntry继承Entry接口,内部实现通过内部类的构造方法保存K,,V
private final K key;
private V value;
public SimpleEntry(K key, V value) {
this.key = key;
this.value = value;
}
该抽象类对于map中通用put方法添加键值对的方式是无效的,调用是会抛出异常。
任何对于entrySet的操作,即取出键值对的集合操作,在此抽象类中均是无效的,必须在实现类中进行具体实现。在Haspmap中,键值对保存的集合为数组类型Entry table[DEFAULT_INITIAL_CAPACITY=16],计算key对象的哈希值。重写entryset方法等。
在此抽象类中,有效操作只能是基于键值对的最基本的getkey,getvalue方法。
自己在实现一个键值对的操作时,我们可以借助map接口和这一个抽象类。
在保存键值对集合时,我们可以使用数组,或者链表。
List<Map.Entry<KeyObject, Object>> returnList = new ArrayList<Map.Entry<KeyObject, Object>>();
Map.Entry<KeyObject, Object> entryTmp = new AbstractMap.SimpleEntry<KeyObject, Object>(K, V);
returnList.add(entryTmp);
在遍历hashmap以及其他实现map的方法时,有两种方法:
1. keyset 遍历;
2. entryset 遍历
而使用第二种方法进行遍历时,我们需要采用Map.Entry<KeyObject, Object> entry为遍历对象,直接对其进行entry.getValue(), entry.getKey() 两种方法操作即可。
for (Map.Entry<KeyObject, Long> entry : hashMap.entrySet()) {
entry.getValue() .....
entry.getKey() .....
}
在已知value的情况下,判断当前map中是否存在该value情况,
调用原生containValue方法即可。
或者使用上述第二种遍历方法,取出键值对中的value进行equal判断。此时进行的操作与原生containvalue方法的原理一致。代码如下:
public boolean containsKey(Object key) {
Iterator<Map.Entry<K,V>> i = entrySet().iterator();
if (key==null) {
while (i.hasNext()) {
Entry<K,V> e = i.next();
if (e.getKey()==null)
return true;
}
} else {
while (i.hasNext()) {
Entry<K,V> e = i.next();
if (key.equals(e.getKey()))
return true;
}
}
return false;
}