[Java基础教程]第十章-Java容器
小明的妈妈再一次让小明去打酱油,这次我们的重构了打酱油流程,先定义一个酱油类,用于在打酱油过程中表示具体的酱油,具体类如下:
publicclassSoy { privateintid; publicSoy(intid) { this.id = id; } }
我们再定义一个商店类,商店需要存货n个酱油,才可以销售,所以我们需要用到集合类持有所有酱油。我们可以使用java.util.List类型的属性,代码如下:
public class Shop {
private String name;
/**
* 酱油列表
*/
private List<Soy> soyList;
public Shop(String name) {
this.name = name;
this.soyList = new ArrayList<Soy>();
int i = 0;
while (i < 100) {
this.soyList.add(new Soy(i++));
}
}
}
代码中有几个知识点:
1、private List<Soy> soyList;查看List的定义发现List是一个接口,声明对象的时候多了一个"<Soy>"泛型定义,soyList只能保存Soy类的对象
2、this.soyList = new ArrayList<Soy>();为变量赋值,ArrayList是List的子类,子类对象可以赋值给父类变量
3、this.soyList.add(new Soy(i++)); List的add方法,向List集合中添加一个对象
4、i++,先做为执行后i=i+1;new Soy(i++),可以分解为new Soy(i);i=i+1;
验证一下商店的酱油情况,代码如下:
public static void main(String[] args) {
Shop shop = new Shop("打酱油便利店");
List<Soy> soyList = shop.getSoyList();
for (int i = 0; i < soyList.size(); i++) {
Soy soy = soyList.get(i);
System.out.println("ID为" + soy.getId() + "的酱油");
}
}
代码中的知识点:
1、soyList.size(),获取当前集合中对象总数量
2、soyList.get(i),返回第i个对象。
商店已经创建了,小明的定义如下:
publicclassPerson { privateString name; privateList<Soy> soyList; publicvoidbuy(Soy soy) { if(soyList == null) { this.soyList = newArrayList<Soy>(); } this.soyList.add(soy); } publicPerson(String name) { this.name = name; } } Person xiaoming = newPerson("小明");
我们再商店添加一下销售方法:
publicbooleansell(Person person, intsize) { if(size > this.soyList.size()) { returnfalse; } for(inti = 0; i < size; i++) { Soy soy = soyList.get(0); person.buy(soy); } for(inti = 0; i < size; i++) { Soy soy = person.getSoyList().get(i); soyList.remove(soy); } returntrue; }
修改main方法:
Person xiaoming = newPerson("小明"); shop.sell(xiaoming, 5); for(inti = 0; i < xiaoming.getSoyList().size(); i++) { Soy soy = xiaoming.getSoyList().get(i); System.out.println(xiaoming.getName() + "购买了ID为"+ soy.getId() + "的酱油"); }
执行结果发现,打印的id都是0,原来小明被商店骗了只给了他一袋酱油,这里我们就可以发现List本身是不能去除重复的,并且是有顺序的。是否有容器满足这个场景,去除重复的对象呢?答案是有,java.util.Set,可以去除重复对象,并且容器是无序的。重构代码如下:
publicclassPerson { privateString name; privateSet<Soy> soyList; publicvoidbuy(Soy soy) { if(soyList == null) { this.soyList = newHashSet<Soy>(); } this.soyList.add(soy); } } publicclassShop { privateString name; privateList<Soy> soyList; publicShop(String name) { this.name = name; this.soyList = newArrayList<Soy>(); inti = 0; while(i < 100) { this.soyList.add(newSoy(i++)); } } publicbooleansell(Person person, intsize) { if(size > this.soyList.size()) { returnfalse; } for(inti = 0; i < size; i++) { Soy soy = soyList.get(0); person.buy(soy); } for(Soy soy : person.getSoyList()) { soyList.remove(soy); } returntrue; } } Person xiaoming = newPerson("小明"); shop.sell(xiaoming, 5); for(Soy soy : xiaoming.getSoyList()) { soyList.remove(soy); }
Set和List的操作很多都类似,因为无序所有没有下标,所以遍历的方式不同。Java在1.5版本以后增加了foreach的遍历方式,for(Object obj : 容器)就是foreach的语法结构,大大简化了原来使用Itrator的方式,使用Itarator的方式如下:
Iterator<Soy> iterator = xiaoming.getSoyList().iterator(); for(; iterator.hasNext();) { Soy soy = iterator.next(); System.out.println(xiaoming.getName() + "购买ID为"+ soy.getId() + "的酱油"); }
现在是打印一个了,数据是正确了,但是商店应该返回size个酱油的,所以我们去把Shop的sell方法修改正确:"Soy soy = soyList.get(i);",再次测试小明确实买到了5个酱油。
商店升级了,可以销售多种品牌的酱油,并且可以分品牌销售,所以我们要按照每个品牌保存一个集合,因为可能存在无限多种品牌,我们不能定义多个List属性,我们需要一个容器可以存储品牌名称(key),对应值(value)这里是List的容器,jdk定义了Map容器支持,支持品牌酱油购买的流程代码重构如下:
//Soy添加String brand属性,并新增入参为id和brand的构造方法 privateString brand; publicSoy(intid, String brand) { this.id = id; this.brand = brand; } //Shop类添加存储品牌酱油列表的Map属性,构造方法中初始化Map,新增购买品牌酱油的方法 privateMap<String, List<Soy>> soys; publicShop(String name) { this.name = name; this.soyList = newArrayList<Soy>(); inti = 0; while(i < 100) { this.soyList.add(newSoy(i++)); } i = 0; soys = newHashMap<String, List<Soy>>(); String brandA = "品牌A"; List<Soy> brandAList = newArrayList<Soy>(); soys.put(brandA, brandAList); while(i < 100) { brandAList.add(newSoy(i++, brandA)); } i = 0; String brandB = "品牌B"; List<Soy> brandBList = newArrayList<Soy>(); soys.put(brandB, brandBList); while(i < 100) { brandBList.add(newSoy(i++, brandB)); } i = 0; String brandC = "品牌C"; List<Soy> brandCList = newArrayList<Soy>(); soys.put(brandC, brandCList); while(i < 100) { brandCList.add(newSoy(i++, brandC)); } i = 0; } publicbooleansell(Person person, intsize, String brand) { List<Soy> list = this.soys.get(brand); if(size < list.size()) { returnfalse; } for(inti = 0; i < size; i++) { Soy soy = list.get(i); person.buy(soy); } for(Soy soy : person.getSoyList()) { list.remove(soy); } returntrue; } //main方法中的执行如下 xiaoming.getSoyList().clear(); shop.sell(xiaoming, 5, "品牌A"); for(Soy soy : xiaoming.getSoyList()) { System.out.println(xiaoming.getName() + "购买品牌为"+ soy.getBrand() + ",ID为"+ soy.getId() + "的酱油"); }
以上代码新知识点:
1、Map属性变量声明,子类HashMap初始化
2、Map的put方法添加键值对
3、Map的get(key)方法获取key对应的值
4、List的clear方法,清空集合
存在一种另外的集合数组,它是java语言支持的容器,工作中某些场合可能会用到,我们把小明买到的酱油使用数组存储,代码如下:
Soy[] soyArray = newSoy[5]; intindex = 0; for(Soy soy : xiaoming.getSoyList()) { soyArray[index++] = soy; } for(Soy soy : soyArray) { System.out.println(xiaoming.getName() + "购买品牌为"+ soy.getBrand() + ",ID为"+ soy.getId() + "的酱油"); }
总结一下,常用容器有4种:
List容器,主要特点有序,值可以重复,主要子类ArrayList,另外一个文章没有提到的LinkedList,在容器中值更新频繁的场合下使用。
Set容器,主要特点,无序,值不可重复,主要子类HashSet
Map容器,键值对存储,无序,不可重复,主要子类HashMap
数组,主要特点有序
小练习:
第八章-Java字符串练习题中,按照a-z出现的次数排序,从高到底依次打印字母和出现次数。
课程中的代码:
packagecom.sunhaojie.learntest.tenth; /** * @ClassName Soy * @Description 酱油实体类 * * @author sunhaojie 3113751575@qq.com * @date 2016年2月3日 下午1:37:02 */ publicclassSoy { /** * 酱油id */ privateintid; /** * 品牌 */ privateString brand; /** * @param id */ publicSoy(intid) { this.id = id; } publicSoy(intid, String brand) { this.id = id; this.brand = brand; } publicintgetId() { returnid; } publicvoidsetId(intid) { this.id = id; } publicString getBrand() { returnbrand; } publicvoidsetBrand(String brand) { this.brand = brand; } } packagecom.sunhaojie.learntest.tenth; importjava.util.ArrayList; importjava.util.HashMap; importjava.util.List; importjava.util.Map; /** * @ClassName Shop * @Description 商店 * * @author sunhaojie 3113751575@qq.com * @date 2016年2月3日 下午2:56:12 */ publicclassShop { /** * 商店名称 */ privateString name; /** * 酱油列表 */ privateList<Soy> soyList; /** * 带有品牌的酱油容器 */ privateMap<String, List<Soy>> soys; /** * @param name */ publicShop(String name) { this.name = name; this.soyList = newArrayList<Soy>(); inti = 0; while(i < 100) { this.soyList.add(newSoy(i++)); } i = 0; soys = newHashMap<String, List<Soy>>(); String brandA = "品牌A"; List<Soy> brandAList = newArrayList<Soy>(); soys.put(brandA, brandAList); while(i < 100) { brandAList.add(newSoy(i++, brandA)); } i = 0; String brandB = "品牌B"; List<Soy> brandBList = newArrayList<Soy>(); soys.put(brandB, brandBList); while(i < 100) { brandBList.add(newSoy(i++, brandB)); } i = 0; String brandC = "品牌C"; List<Soy> brandCList = newArrayList<Soy>(); soys.put(brandC, brandCList); while(i < 100) { brandCList.add(newSoy(i++, brandC)); } i = 0; } /** * * @Title sell * @Description 销售酱油 * @param person * @param size * @return * @return boolean * * @author sunhaojie 3113751575@qq.com * @date 2016年2月3日 下午5:05:08 */ publicbooleansell(Person person, intsize) { if(size > this.soyList.size()) { returnfalse; } for(inti = 0; i < size; i++) { Soy soy = soyList.get(i); person.buy(soy); } for(Soy soy : person.getSoyList()) { soyList.remove(soy); } returntrue; } /** * * @Title sell * @Description 按照品牌销售酱油 * @param person * @param size * @param brand * @return * @return boolean * * @author sunhaojie 3113751575@qq.com * @date 2016年2月3日 下午10:34:05 */ publicbooleansell(Person person, intsize, String brand) { List<Soy> list = this.soys.get(brand); if(size > list.size()) { returnfalse; } for(inti = 0; i < size; i++) { Soy soy = list.get(i); person.buy(soy); } for(Soy soy : person.getSoyList()) { list.remove(soy); } returntrue; } publicString getName() { returnname; } publicvoidsetName(String name) { this.name = name; } publicList<Soy> getSoyList() { returnsoyList; } publicvoidsetSoyList(List<Soy> soyList) { this.soyList = soyList; } } packagecom.sunhaojie.learntest.tenth; importjava.util.HashSet; importjava.util.Set; /** * @ClassName Person * @Description 人 * * @author sunhaojie 3113751575@qq.com * @date 2016年2月3日 下午1:38:30 */ publicclassPerson { /** * 名字 */ privateString name; /** * 酱油列表 */ privateSet<Soy> soyList; /** * * @Title buy * @Description 买酱油 * @param soy * @return void * * @author sunhaojie 3113751575@qq.com * @date 2016年2月3日 下午4:59:31 */ publicvoidbuy(Soy soy) { if(soyList == null) { this.soyList = newHashSet<Soy>(); } this.soyList.add(soy); } /** * @param name */ publicPerson(String name) { this.name = name; } publicString getName() { returnname; } publicvoidsetName(String name) { this.name = name; } publicSet<Soy> getSoyList() { returnsoyList; } publicvoidsetSoyList(Set<Soy> soyList) { this.soyList = soyList; } } packagecom.sunhaojie.learntest.tenth; importjava.util.Iterator; importjava.util.List; /** * @ClassName DaJiangYou * @Description 打酱油测试集合 * * @author sunhaojie 3113751575@qq.com * @date 2016年2月3日 下午3:36:03 */ publicclassDaJiangYou { /** * @Title main * @Description main方法 * @param args * @return void * * @author sunhaojie 3113751575@qq.com * @date 2016年2月3日 下午3:36:03 */ publicstaticvoidmain(String[] args) { Shop shop = newShop("打酱油便利店"); List<Soy> soyList = shop.getSoyList(); for(inti = 0; i < soyList.size(); i++) { Soy soy = soyList.get(i); System.out.println("ID为"+ soy.getId() + "的酱油"); } Person xiaoming = newPerson("小明"); shop.sell(xiaoming, 5); for(Soy soy : xiaoming.getSoyList()) { System.out.println(xiaoming.getName() + "购买ID为"+ soy.getId() + "的酱油"); } Iterator<Soy> iterator = xiaoming.getSoyList().iterator(); for(; iterator.hasNext();) { Soy soy = iterator.next(); System.out.println(xiaoming.getName() + "购买ID为"+ soy.getId() + "的酱油"); } xiaoming.getSoyList().clear(); shop.sell(xiaoming, 5, "品牌A"); for(Soy soy : xiaoming.getSoyList()) { System.out.println(xiaoming.getName() + "购买品牌为"+ soy.getBrand() + ",ID为"+ soy.getId() + "的酱油"); } Soy[] soyArray = newSoy[5]; intindex = 0; for(Soy soy : xiaoming.getSoyList()) { soyArray[index++] = soy; } for(Soy soy : soyArray) { System.out.println(xiaoming.getName() + "购买品牌为"+ soy.getBrand() + ",ID为"+ soy.getId() + "的酱油"); } } }
建议继续学习:
- Kubernetes – Google分布式容器技术初体验 (阅读:3607)
- 基于管道模式的容器设计 (阅读:2372)
- Ext JS 4 布局和容器:Layouts、Containers (阅读:2172)
- docker容器监控的实现 (阅读:1745)
- 【死磕Java并发】—–J.U.C之Java并发容器:ConcurrentLinkedQueue (阅读:1381)
- 视频的容器与格式 (阅读:912)
扫一扫订阅我的微信号:IT技术博客大学习
- 作者:sunhaojie 来源: 孙豪杰的博客
- 标签: 容器
- 发布时间:2016-02-21 22:42:33
- [66] Oracle MTS模式下 进程地址与会话信
- [65] Go Reflect 性能
- [64] 如何拿下简短的域名
- [60] android 开发入门
- [59] 图书馆的世界纪录
- [59] 【社会化设计】自我(self)部分――欢迎区
- [58] IOS安全–浅谈关于IOS加固的几种方法
- [54] 视觉调整-设计师 vs. 逻辑
- [47] 界面设计速成
- [47] 读书笔记-壹百度:百度十年千倍的29条法则