持有对象指的是Java中保存对象的方式,这次我们主要谈论是Java中的容器类。
Java内的容器类可以划分为两种:
①Collection。一个独立的元素序列,这些元素都服从一条或多条规则。常用的有List,Set,Queue,Stack等等。
②Map。一组成对的“键值对”对象,允许我们使用键来查找值。
Collection 接口概括了序列概念,关于List,Set等这些类的基本方法,在平时开发中经常用到对于其包含的基本方法就不一一介绍了,另外值得提一下的是 java.util包中的Arrays和Collections类中包含了很多实用的方法,例如:Arrays.asList()方法接受一个数组,或者 是用都好分隔的元素列表,并将其转换为List对象。
关于Arrays.asList()方法只是对它所产生的List类型做出理想的假设,并不会检测你声明类型,进行转型,通过下面这个例子可以看出这一点:
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
class Snow{}
class Powder extends Snow{}
class Light extends Powder{}
class Heavy extends Powder{}
class Crusty extends Snow{}
class Slush extends Snow{}
public class AsListInference {
public static void main(String[] args) {
List<Snow> snow1 = Arrays.asList(new Crusty(), new Slush(), new Powder());
// List<Snow> snow2 = Arrays.asList(new Light(), new Heavy());
List<Snow> snow3 = new ArrayList<Snow>();
Collections.addAll(snow3, new Light(), new Heavy());
List<Snow> snow4 = Arrays.<Snow>asList(new Light(), new Heavy());
}
}
其中snow2与snow5注释掉了,
snow2报错为:Type mismatch: cannot convert from List<Powder> to List<Snow>
当 试图创建snow2是只有Powder类型,所以会创建List<Powder>而不是List<Snow>,如果 asList()方法参数中含有不同类,则试图生成最上层的基类,或者Object的List。也可以像snow4中,告诉编译器生成Snow类型的 List。
在使用容器类时我们经常使用到迭代器。迭代器是一个对象,它的工作室遍历并选择序列中的对象,而客户端程序员不必知道该序列的底层结构。所以我们可以看出迭代器的真正优势在于:能够将遍历序列的操作与底层序列的结构分离,统一了我们对容器的访问方式。
如果我们编写了一个方法,其接受一个Collection的参数,我们有两种方式(1)通过继承AbstractCollection
public class CollectionSequence extends AbstractCollection<Snow>{
private Snow[] snows = {new Snow(), new Snow(), new Snow()};
public Iterator<Snow> iterator(){
return new Iterator<Snow>() {
private int index = 0;
@Override
public void remove() {
throw new UnsupportedOperationException();
}
@Override
public Snow next() {
return snows[index++];
}
@Override
public boolean hasNext() {
return index < snows.length;
}
};
}
@Override
public int size() {
return snows.length;
}
}
(2)通过实现collection接口中的方法
class SnowSequence{
protected Snow[] snows = {new Snow(), new Snow(), new Snow()};
}
public class NonCollectionSequence extends SnowSequence{
public Iterator<Snow> iterator(){
return new Iterator<Snow>() {
private int index = 0;
@Override
public void remove() {
throw new UnsupportedOperationException();
}
@Override
public Snow next() {
return snows[index++];
}
@Override
public boolean hasNext() {
return index < snows.length;
}
};
}
}
可以看出我们可以通过继承AbstractCollection很容易实现,但此时必须强制的实现iterator()和size()方法,而且此时可以 使用foreach结构,如果我们的类已经继承了其他的类就必须通过第二种方式实现了。这里面用到了我们前面提到的匿名内部类。