java基础之怀有对象

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