集合以前一直不懂,今天也是差不多看懂了。不过,看数据结构!看数据结构!看数据结构!重要的事说三遍。感觉自己学的还很浅,太多东西一下子接受不了。
1. Iterator是什么?
迭代器(Iterator)
迭代器是一种设计模式,它是一个对象,它可以遍历并选择序列中的对象,而开发人员不需要了解该序列的底层结构。迭代器通常被称为“轻量级”对象,因为创建它的代价小。
Java中的Iterator功能比较简单,并且只能单向移动:
(1) 使用方法iterator()要求容器返回一个Iterator。第一次调用Iterator的next()方法时,它返回序列的第一个元素。注意:iterator()方法是java.lang.Iterable接口,被Collection继承。
(2) 使用next()获得序列中的下一个元素。
(3) 使用hasNext()检查序列中是否还有元素。
(4) 使用remove()将迭代器新返回的元素删除。
Iterator是Java迭代器最简单的实现,为List设计的ListIterator具有更多的功能,它可以从两个方向遍历List,也可以从List中插入和删除元素。
迭代器应用:
list l = new ArrayList();
l.add("aa");
l.add("bb");
l.add("cc");
for (Iterator iter = l.iterator(); iter.hasNext();) {
String str = (String)iter.next();
System.out.println(str);
}
/*迭代器用于while循环
Iterator iter = l.iterator();
while(iter.hasNext()){
String str = (String) iter.next();
System.out.println(str);
}
*/
2. Array和ArrayList有何区别?什么时候更适合用Array?
ArrayList是Array的复杂版本
ArrayList内部封装了一个Object类型的数组,从一般的意义来说,它和数组没有本质的差别,甚至于ArrayList的许多方法,如Index、IndexOf、Contains、Sort等都是在内部数组的基础上直接调用Array的对应方法。
内部的Object类型的影响
对于一般的引用类型来说,这部分的影响不是很大,但是对于值类型来说,往ArrayList里面添加和修改元素,都会引起装箱和拆箱的操作,频繁的操作可能会影响一部分效率。
但是恰恰对于大多数人,多数的应用都是使用值类型的数组。
消除这个影响是没有办法的,除非你不用它,否则就要承担一部分的效率损失,不过这部分的损失不会很大。
数组扩容
这是对ArrayList效率影响比较大的一个因素。
每当执行Add、AddRange、Insert、InsertRange等添加元素的方法,都会检查内部数组的容量是否不够了,如果是,它就会以当前容量的两倍来重新构建一个数组,将旧元素Copy到新数组中,然后丢弃旧数组,在这个临界点的扩容操作,应该来说是比较影响效率的。
频繁的调用IndexOf、Contains等方法(Sort、BinarySearch等方法经过优化,不在此列)引起的效率损失
首先,我们要明确一点,ArrayList是动态数组,它不包括通过Key或者Value快速访问的算法,所以实际上调用IndexOf、Contains等方法是执行的简单的循环来查找元素,所以频繁的调用此类方法并不比你自己写循环并且稍作优化来的快,如果有这方面的要求,建议使用Hashtable或SortedList等键值对的集合。
3. ArrayList和LinkedList有何区别?
ArrayList数组线性表的特点为:类似数组的形式进行存储,因此它的随机访问速度极快。
ArrayList数组线性表的缺点为:不适合于在线性表中间需要频繁进行插入和删除操作。因为每次插入和删除都需要移动数组中的元素。
LinkedList的链式线性表的特点为: 适合于在链表中间需要频繁进行插入和删除操作。
LinkedList的链式线性表的缺点为: 随机访问速度较慢。查找一个元素需要从头开始一个一个的找。速度你懂的
4. 哪些集合类是线程安全的?
vector:就比arraylist多了个同步化机制(线程安全),因为效率较低,现在已经不太建议使用。在web应用中,特别是前台页面,往往效率(页面响应速度)是优先考虑的。
statck:堆栈类,先进后出
hashtable:就比hashmap多了个线程安全
enumeration:枚举,相当于迭代器
除了这些之外,其他的都是非线程安全的类和接口。
线程安全的类其方法是同步的,每次只能一个访问。是重量级对象,效率较低。
5. Collections类是什么?
Collection是一个接口类,其继承了java迭代接口Iterable。
Collection接口有两个主要的子接口List和Set,注意Map不是Collection的子接口哦这个要牢记。
Collection中可以存储的元素间无序,可以重复组各自独立的元素,即其内的每个位置仅持有一个元素,同时允许有多个null元素对象。
6. Comparable和Comparator接口是什么?
(一).关于Comparable接口(TreeSet实现排序方法一)
此接口强行对实现它的每个类(引用类型 )的对象进行整体排序。这种排序被称为类的自然排序,类的 compareTo 方法被称为它的自然比较方法。 实现此接口的对象列表(和数组)可以通过 Collections.sort(和 Arrays.sort)进行自动排序。实现此接口的对象可以用作有序映射中的键或有序集合中的元素,无需指定比较器。 此接口下只有只有一个方法:(int)compareTo(Object ob)
此方法比较指定对象的排序,返回值是一个int类型,如果该对象小于、等于或大于指定对象,则分别返回负整数、零或正整数。
(二). 关于Comparator接口(TreeSet实现排序方法二)
强行对某个对象 collection (集合)进行整体排序 的比较函数。 此接口有一个方法:
(int)compareTo(Object 0b1,Object ob2); 比较用来排序的两个参数
假如说我们要想TreeSet中插入对象所属的类没有实现Comparable接口,没有对comapareTo的方法进行实现的,我们可以实现比较器(Comparator),同样可以实现排序的功能,并按照我们所需要的方法去排序。
7. Collection接口的常用方法哪些?
方法 | 描述 |
Boolean add(Object o) | 向集合中添加一个对象的引用 |
Void clear() | 删除集合中的所有对象,即不再持有这些对象的引用 |
Boolean contains(Object o) | 判断在集合中是否持有特定对象的引用 |
Boolean isEmpty() | 判断集合是否为空 |
Iterator iterator() | 返回一个Iterator对象,可用它来遍历集合中的元素 |
Boolean remove(Object o) | 从集合中删除一个对象的引用 |
Boolean retainAll(Collection<?> c) | 保留集合中的指定内容 |
Int size() | 返回集合中元素的数目 |
Object[] toArray() | 返回一个数组,该数组包含集合中的所有元素
|
Boolean equals(Object o) | 对象比较 |
Int hashCode() | 返回hash码 |
8. http://jingyan.baidu.com/article/8065f87ff69c2623312498ce.html这里的问题都要搞明白。
9. Linkedlist,arraylist,hashmap的遍历程序。
Arraylist:
List<String> list=new ArrayList<String>();
list.add("Hello");
list.add("World");
list.add("HAHAHAHA");
//第一种遍历方法使用foreach遍历List
for (String str : list){ //也可以改写for(int i=0;i<list.size();i++)这种形式
System.out.println(str);
}
//第二种遍历,把链表变为数组相关的内容进行遍历
String[]strArray=new String[list.size()];
list.toArray(strArray);
for(int i=0;i<strArray.length;i++) //这里也可以改写为foreach(String str:strArray)这种形式
{
System.out.println(strArray[i]);
}
//第三种遍历 使用迭代器进行相关遍历
Iterator<String>ite=list.iterator();
while(ite.hasNext())
{
System.out.println(ite.next());
}
Linkedlist:
List<String> list=new LinkedList<String>();
list.add("Hello");
list.add("World");
list.add("龙不吟,虎不啸");
//LinkedList遍历的第一种方式使用数组的方式
String[]strArray=new String[list.size()];
list.toArray(strArray);
for(Stringstr:strArray)
{
System.out.println(str);
}
//LinkedList遍历的第二种方式
for(Stringstr:list)
{
System.out.println(str);
}
Hashmap:
第一种:
Map map = newHashMap();
Iterator iter =map.entrySet().iterator();
while (iter.hasNext()) {
Map.Entry entry =(Map.Entry) iter.next();
Object key = entry.getKey();
Object val = entry.getValue();
}
效率高,以后一定要使用此种方式!
第二种:
Map map = newHashMap();
Iterator iter =map.keySet().iterator();
while (iter.hasNext()) {
Object key = iter.next();
Object val = map.get(key);
}
效率低,以后尽量少使用!
HashMap的遍历有两种常用的方法,那就是使用keyset及entryset来进行遍历,但两者的遍历速度是有差别的
编程题
1. 用Java模拟一个堆栈或者队列数据结构。
package com.jiale.demo01;
import java.util.LinkedList;
public class Stack {
public static void main(String[] args) {
// TODO自动生成的方法存根
StackTools tools = new StackTools();
tools.add("a");
tools.add("b");
tools.add("c");
tools.add("d");
tools.remove();
}
}
class StackTools {
private LinkedList<String> linkedList;
public StackTools(){
linkedList = new LinkedList<String>();
}
public void add(String string){
linkedList.addFirst(string);
}
public void remove(){
for(String str:linkedList){
System.out.println(str);
}
}
}
运行结果:
d
c
b
a
package com.jiale.demo01;
import java.util.LinkedList;
public class Queue {
public static void main(String[] args) {
// TODO自动生成的方法存根
QueueTools tools = new QueueTools();
tools.add("a");
tools.add("b");
tools.add("c");
tools.add("d");
tools.remove();
}
}
class QueueTools {
private LinkedList<String> linkedList;
public QueueTools(){
linkedList = new LinkedList<String>();
}
public void add(String string){
linkedList.addLast(string);
}
public void remove(){
for(String str:linkedList){
System.out.println(str);
}
}
}
运行结果:
a
b
c
d
栈是一种数据结构,只能从一端进行存储和访问。常规操作有压入栈和弹出栈。
特性:后进先出
以下是用ArrayList为内核实现一个栈的数据结构
注:栈作为一种数据结构,是一种只能在一端进行插入和删除操作的特殊线性表。它按照后进先出的原则存储数据,先进入的数据被压入栈底,最后的数据在栈顶,需要读数据的时候从栈顶开始弹出数据(最后一个数据被第一个读出来)。栈具有记忆作用,对栈的插入与删除操作中,不需要改变栈底指针。
package com.jiale.demo02;
import java.util.LinkedList;
public class MyStack {
private LinkedList linkedList;
public MyStack() {
// TODO自动生成的构造函数存根
linkedList = new LinkedList();
}
/**
* 压入栈顶
* @param o
*/
public void push(Object o){
linkedList.addFirst(o);
}
/**
* 弹出;移除栈顶对象,并作为函数的值返回该对象。
* @return
*/
public Object pop(){
if(linkedList.isEmpty()){
System.out.println("栈为空,不能出栈!");
return null;
}
return linkedList.removeFirst();
}
/**
* 查看栈顶对象而不移除它。
* @return
*/
public Object peek(){
return linkedList.getFirst();
}
/**
* 测试堆栈是否为空。
* @return
*/
public boolean empty(){
return linkedList.isEmpty();
}
}
package com.jiale.demo02;
public class Demo02 {
public static void main(String[] args) {
// TODO自动生成的方法存根
MyStack ms = new MyStack();
ms.push("a");
ms.push("b");
ms.push("c");
System.out.println(ms.pop());
System.out.println(ms.peek());
System.out.println(ms.empty());
}
}
运行结果:
c
b
false