IT技术博客大学习 共学习 共进步
全部 移动开发 后端 数据库 AI 算法 安全 DevOps 前端 设计 开发者

[Java基础教程]第十章-Java容器

孙豪杰的博客 2016-02-21 22:42:33 累计浏览 2,782 次
本机暂存

小明的妈妈再一次让小明去打酱油,这次我们的重构了打酱油流程,先定义一个酱油类,用于在打酱油过程中表示具体的酱油,具体类如下:

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() + "的酱油");
        }
    }
}

同分类推荐文章

  1. 等了十年的 Go 链式管道,终于来了:seq 让你像写 Scala 一样写 Go (2026-06-25 18:38:18)
  2. Go 实验特性详解 (2026-06-21 10:05:27)
  3. amd64 微架构级别对 Go 程序性能提升多少? (2026-06-21 09:38:49)

查看更多 后端 文章 →

建议继续学习

  1. SmartSprites - 命令行形式的CSS Sprites生成器 (累计阅读 123,894)
  2. Java开发岗位面试题归类汇总 (累计阅读 22,155)
  3. 红黑树并没有我们想象的那么难(上) (累计阅读 21,493)
  4. android 开发入门 (累计阅读 19,526)
  5. 我的PHP,Python和Ruby之路 (累计阅读 13,146)
  6. HashMap解决hash冲突的方法 (累计阅读 12,652)
  7. 为什么算法这么难? (累计阅读 12,394)
  8. 浅谈MySQL索引背后的数据结构及算法 (累计阅读 11,900)
  9. 加州求职记 (累计阅读 11,560)
  10. 海量数据面试题举例 (累计阅读 11,111)