十一 容器类

 

 

容器类

----通常,程序总是根据运行时才知道的某些条件去创建新的对象。在此之前,不会知道所需对象的数量、确切的类型。当然不能依靠创建命名的引用来持有每个对象。Java有多种方式保存对象(对象的引用),如较为简单直接有效方式数组,但是数组的尺寸大小固定,当时当你写的程序连你都不知道有多少个对象需要你来承接的时候,Java类库中的容器类(自动调节自身尺寸)就能大显身手了!

基本容器类有List、Set、Map。当然也有称其为集合类,Java的类库中使用了Collection这个名词来指代该类的一个特殊子集。当然他们各自有各自的特性。例如,Set对于每个值都只保存一个对象(去重),Map是允许你将对象和对象关联起来存储。在强调容器类会根据对象的数量自动调节自身大小 ------妈妈再也不用担心下标越界了!!

1 基本概念

 注意:Java 容器类用途就是保存对象(对象引用)。

  • Collection。独立元素的序列,此元素须满足一至多条规则,如List须满足按照插入顺序保存元素,而Set不会有重复元素。Queue按照排队规则来确定对象产生顺序(插入顺序)
  • Map。一组key-value对象,使用key来查找value.也即为用键对象查找值对象。对象与对象形成的键-值也称为“关联数组”,就如同字典的单词查找一般。

首先创建个类

public class Gerbil {
 private int gerbilNumber;
 public void setGerbilNumer(int gerbilNumber) {
	 this.gerbilNumber=gerbilNumber;
 }
 public int getGerbilNumber() {
	 return gerbilNumber;
 }
 
 public String hop() {
	 return "沙鼠步数"+gerbilNumber;
 }
 
}

你可以创建一个List:

当然最好List<Gerbil> gerbilList =  new ArrayList<Gerbil>(); 注意这里的ArrayList已经上转型为List。使用接口的目的在于如果你决定去修改你的实现,你只需要在创建处修改即可。

List<Gerbil> gerbilList =  new LinkedList<Gerbil>();

因此,应该创建一个具体类对象,将其转型为对应接口,然后在其余代码中使用该接口。

如代码,foreach选择List中的每一个元素,Collection.addAll()可以接受一个Collection对象实现添加一组元素的效果。


import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

/*
 * @author jack
 * 2019/4/11
 */
public class AddingGroups {
	/*
	 * 添加List容器对象(对象的引用)
	 */
	public List<Gerbil> setGerbilList() {
		List<Gerbil> gerbilList =  new ArrayList<Gerbil>();
		for (int i = 0;i < 5;i ++) {
			Gerbil gerbil =new Gerbil();
			gerbil.setGerbilNumer(i);
			gerbilList.add(gerbil);
		}
		return gerbilList;
	}
	
	public static void main(String[] args) {
		AddingGroups addingGroups = new AddingGroups();
		 ArrayList<Gerbil> gerbilLists = (ArrayList<Gerbil>) addingGroups.setGerbilList();
		 List<Gerbil> lists = new ArrayList<Gerbil>();
		 lists.addAll(gerbilLists);
		 for (Gerbil gerbil : gerbilLists) {
				System.out.println("ArrayList"+gerbil.hop());
			}
		 for (Gerbil gerbil : lists) {
				System.out.println("List"+gerbil.hop());
			}
		Iterator<Gerbil> gIterator = lists.iterator();
		while (gIterator.hasNext()) {
			Gerbil gerbil = (Gerbil) gIterator.next();
			System.out.println("Iterator"+":"+gerbil.hop());
		}

	 }
}

输出:

ArrayList沙鼠步数2
ArrayList沙鼠步数3
ArrayList沙鼠步数4
List沙鼠步数0
List沙鼠步数1
List沙鼠步数2
List沙鼠步数3
List沙鼠步数4

 

2 List

List承诺可以将元素维护在特定的序列中。List在Collection的基础上添加了大量的方法,使其可以在List中插入和移除元素

两类List:

  • 基本的ArrayList,擅长随机访问元素,但是在List中间插入、删除比较慢
  • LinkList,擅长中间插入、删除。但是随机访问比较慢,但是LinkList的特性集比ArrayList大(https://www.cnblogs.com/lintong/p/4374292.html)作为参考了解

 简单解释:如getFirst()、element()完全一样,都是返回list的第一个元素(返回而非移除),如果List为空则抛出NoSouchElementException。peek()与上两方法稍有差异,当List为空则返回NULL。removeFirst()、remove()和poll()与上诉方法差异一致。

3 Set

Set不保存重复的元素。Set具有Collection完全一样的接口,故没有什么额外的功能,不像前面的List(当然这也是继承和多态的典型应用:表现不同的行为)

4 Map

将对象映射到其他对象的能力是解决编程问题的利剑。

  • Map提供了一种映射关系,其中的元素是以键值对(key-value)的形式存储的,能够实现根据key快速查找value;
  • Map中的键值对以Entry类型的对象实例形式存在;
  • 键(key值)不可重复,value值可以重复,一个value值可以和很多key值形成对应关系,每个建最多只能映射到一个值。
  • Map支持泛型,形式如:Map<K,V>
  • Map中使用put(K key,V value)方法添加

如下代码测试random类的随机性

import java.util.HashMap;
import java.util.Map;
import java.util.Random;

public class MapStatistic {
public static void main(String[] args) {
	Random random = new Random(49);
	Map<Integer, Integer> map = new HashMap<Integer, Integer>();
	for (int i = 0 ; i < 100; i++) {
		int r = random.nextInt(20);
		Integer freq = map.get(r);
		map.put(r, freq == null ? 1 : freq + 1);
	}
	System.out.println(map);
}
}

如果Key 值不在容器中get()将返回NULL,get()返回对应的Value(Integer引用)最终得到一下结果:

{0=6, 1=5, 2=4, 3=5, 4=7, 5=3, 6=6, 7=4, 8=7, 9=6, 10=7, 11=7, 12=3, 13=4, 14=3, 15=4, 16=3, 17=8, 18=6, 19=2}

 

import java.util.ArrayList;
import java.util.Map;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import practise.Gerbil;

/*
 * @author jack
 * 学习验证对象类特性 */
public class ListPractise {
	/*
	 * 添加List容器对象(对象的引用)
	 */
	public List<Gerbil> setGerbilList() {
		List<Gerbil> gerbilList =  new ArrayList<Gerbil>();
		for (int i = 0;i < 5;i ++) {
			Gerbil gerbil =new Gerbil();
			gerbil.setGerbilNumer(i);
			gerbilList.add(gerbil);
		}
		return gerbilList;
	}
	
	/*
	 * 添加set容器对象
	 */
	public Set<Gerbil> setGerbilSet() {
		Set<Gerbil> gerbilSet = new HashSet<Gerbil>();
		for (int i = 0; i < 5 ; i ++) {
			Gerbil gerbil = new Gerbil();
			gerbil.setGerbilNumer(i);
			gerbilSet.add(gerbil);
		}
		return gerbilSet;
	}
	
	/*
	 * 添加Map容器对象
	 */
	public Map<String, Gerbil> setGerbilMap(){
		Map<String, Gerbil> gerbilMap = new HashMap<String, Gerbil>();
		for(int i = 0; i < 5 ; i ++) {
			Gerbil gerbil = new Gerbil();
			gerbil.setGerbilNumer(i);
			gerbilMap.put("第"+i, gerbil);
		}
		return gerbilMap;
	}
	
	public static void main(String[] args) {
		 ListPractise lPractise = new ListPractise();
		 ArrayList<Gerbil> gerbilLists = (ArrayList<Gerbil>) lPractise.setGerbilList();
		 Set<Gerbil> gerbilSet = lPractise.setGerbilSet();
		 Iterator<Gerbil> gIterator = gerbilLists.iterator();
		 while (gIterator.hasNext()) {
			Gerbil gerbil = (Gerbil) gIterator.next();
			System.out.println("Iterator"+":"+gerbil.hop());
		}
		 for (Gerbil gerbil : gerbilLists) {
			System.out.println("List"+gerbil.hop());
		}
		 for (Gerbil gerbil : gerbilSet) {
			System.out.println("Set"+gerbil.hop());
		}
	 }
}

总结:

  1. 数组将数字与对象联系起来。保存类型明确的对象,查询对象是不需要对对象结果做类型转换。当然可以保存基本类型的数据。数组是一旦生成容量不可改变!
  2. Coullection 保存单一元素,而Map保存键值对。在Java泛型的基础上可以指定存放得数据类型,如此也避免了错误类型对象放入容器中。且在获取对象时不必做类型转换。容器则不能持有基本的数据类型,优势则是在再添加更多元素的时候自动调节元素尺寸。
  3. List 可以像素组一样建立数字索引与对象的关联,故数组和List都是排好顺序的容器
  4. 如果大量随机访问则使用ArrayList,若是常从中间插入或删除元素则用LinkedList
  5. LinkedList可以实现Queue以及栈的行为。
  6. Set不接受重复的元素。HashSet提供较快的查询速度,TreeSet保持元素的排序状态,LinkedHashSet已插入顺序保持元素。
  7. Map 是将对象和对象进行关联的设计。HashMap设计用来快速访问;而TreeMap保持Key始终排序状态,所以没有HashMap快,LinkedHashMap保持元素插入的顺序,且通过散列提供了快速访问的能力。
  8. 新程序不易使用Vector、HashTable、Stack
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值