java基础之怀有对象
持有对象指的是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结构,如果我们的类已经继承了其他的类就必须通过第二种方式实现了。这里面用到了我们前面提到的匿名内部类。