Java 实验6 集合类

实验6 集合类

一、实验目的

了解集合的定义和分类,掌握List接口 、Set接口 、Map接口的实现类,掌握使用Collections工具类和Arrays工具类操作集合。

二、程序理解:

Java中的集合都是由一些接口,抽象类及它们的实现类所组成。而它们全部封装在java.util包中。

(1)List

下面的代码将利用LinkedList来实现一个栈的基本功能

import java.util.LinkedList;
public class MockStack {
    private LinkedList data = new LinkedList();
    public boolean idEmpty(){
        return data.isEmpty();
    }
    public Object top(){
        //取栈顶元素相当于取LinkedList容器的头位置的元素
        return data.getFirst();
    }
    public void push(Object element){
        //压入元素相当于在LinkedList容器的头位置插入元素
        data.addFirst(element);
    }
    public void pop(){
        //弹出元素相当于删除LinkedList容器的头位置的元素
        data.removeFirst();
    }
    public String toString(){
        return data.toString();
    }
    public static void main(String[] args){
        MockStack stack = new MockStack();
        //下面的语句使用LinkedList实现的堆栈的用法
        stack.push("Shandong");
        stack.push("University Of Technology");
        stack.push("StephenLi");
        while (!stack.idEmpty()){
            System.out.println("即将弹出的成员是:" + stack.top());
            stack.pop();
            System.out.println("当前栈中剩余的成员为:" + stack);
        }
    }
}

运行结果:
这里写图片描述

(2)set

HashSet为快速查找而设计的Set,存入HashSet的对象必须定义HashCode方法,其底层实现是一个哈希表,存入HashSet中的元素没有顺序性。TreeSet为保持Set中成员有序而设计的一个Set的子类,存入TreeSet中的对象如果实现了Comparable接口,则将按照该接口的compareTo方法比较大小后按照升序排列,程序员也可以在构造方法中直接指定比较器。LinkedHashSet具有HashSet的查询速度,且底层使用链表维护元素的顺序,也就是说元素的顺序与插入的顺序相同(注意与TreeSet中元素的顺序区别)。
下面就演示一下这三种类型的Set的特点

package net.chelson.chapter9;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.Set;
import java.util.TreeSet;
public class SetTest {
    //测试插入重复数据的情况
    public void testRebundant(Set set) {
        set.add("chelson");
        set.add("chelson");
        set.add("chelson");
        System.out.println("插入重复数据后"+ set.getClass().getName() +"的成员为: " + set);
    }
    //测试set内部元素排列顺序
    public void testOrder(Set set) {
        set.add("b");
        set.add("a");
        set.add("c");
        System.out.println(set.getClass().getName() +"的成员顺序是: " + set);
    }
    public static void main(String[] args) {
        SetTest st = new SetTest();
        st.testOrder(new HashSet());
        st.testOrder(new LinkedHashSet());
        st.testOrder(new TreeSet());
        st.testRebundant(new HashSet());
        st.testRebundant(new LinkedHashSet());
        st.testRebundant(new TreeSet());
    }
}

运行结果:
这里写图片描述

(3)迭代器

  迭代器是一种常用的模式,习惯上称之为“迭代器模式”或“Iterator模式”。该模式是用于遍历集合类的标准访问方法。它可以把访问逻辑从不同类型的集合类中抽象出来,从而避免向客户端暴露集合的内部结构。
如果没有使用迭代器模式,我们如果想要遍历一个ArrayList代码只能用下面的实现

for (int i = 0; i < list.size(); i ++){
    list.get(i);
}

  这种方法程序员必须事先知道几何的内部结构,访问代码和集合本身是紧耦合,无法将访问逻辑从集合类和客户端代码中分离出来,每一种集合对应一种遍历方法,客户端代码无法复用。而且如果想要遍历Set类型的集合,java类库中并没有提供合适的方法,更糟的是假设程序员在程序运行一段时间后发现需要一个不能有重复成员的集合,此时将List更改成Set完全无法工作,因为Set接口没有get方法。
  而Iterator模式则规定对所有的集合采用同一种方式遍历成员,在Java类库中,所有实现Collection接口的类都可以通过方法iterator()获取一个能够遍历其所有成员的迭代器,因此,上面的例子改成下面的代码后,如果想要更改List接口为Set接口将是轻而易举的事情;

Iteator iter = list.iterator();
while (iter.hasNext()){
    iter.next();
}

转变成Set接口只要修改一处代码即可

Iteator iter = set.iterator();
while (iter.hasNext()){
    iter.next();
}

所有类型集合生成的迭代器都必须实现Iterator接口,但是其实现方式可以完全不一样,只要实现了Iterator接口以下三个方法就可以了;

boolean hashNext();
Object next();
void remove();

下面代码自己来设计一个支持迭代器的容器:

import java.util.*;

public class IterableClass implements Iterable<String>
{
    protected String[] words=("And that is how "+"we know the earth to be banana-shaped").split(" ");

    public Iterator<String> iterator()
    {
        return new Iterator<String>() 
        {
            private int index=0;
            public boolean hasNext()
            {
                return index < words.length;
            }
            public String next(){ return words[index++]; }
            public void remove() 
            { throw new UnsupportedOperationException(); }
        };
    } 




    public static void main(String[] args)
    {
        for(String s: new IterableClass())
            System.out.print(s+" ");
    }
}

运行结果:
这里写图片描述

三、编程题

(1)教材279页编程题第1题;
(2)教材280页编程题第2题;
(3)教材280页编程题第3题。
(4)(选做题)写一个彩票程序:30选7。随机(1~30之间)生成7个随机数,注意不能重复。然后从键盘输入7个数,对比7个数是否与随机数有相同的。最后显示“中了几个号”。同时,如果中了7个号,显示一等奖;如果中了6个号,显示二等奖;如果中了5个号,显示三等奖。要求:选用合适的容器和算法。(说明:键盘输入可以使用Scanner类)

四、实验结果

(1)程序1运行结果

这里写图片描述

(2)程序2运行结果

这里写图片描述

(3)程序3运行结果

这里写图片描述

(4)程序4运行结果(如选做)

这里写图片描述

五、实验源代码

(1)程序1源代码

package test6;

import java.util.*;

public class Example1 {

    public static void main(String[] args) {
        ArrayList list = new ArrayList(); // 创建ArrayList集合
        list.add("stu1"); // 向该集合添加元素
        list.add("stu2");
        list.add("stu3");
        list.add("stu4");
        list.add("stu5"); // 向该集合添加元素
        list.add("stu6");
        list.add("stu7");
        list.add("stu8");
        list.add("stu9"); // 向该集合添加元素
        list.add("stu0");
        Iterator it = list.iterator(); // 获取Iterator对象
        while (it.hasNext()) { // 判断ArrayList集合中是否存在下一个元素
            Object obj = it.next(); // 取出ArrayList集合中的元素
            System.out.print(obj+"  ");
        }
    }

}

(2)程序2源代码

package test6;

import java.util.*;

class Person {
    private String age;
    private String name;

    public Person(String age, String name) {
        this.age = age;
        this.name = name;
    }

    // 重写toString()方法
    public String toString() {
        return name + "," + age;
    }

    // 重写hashCode方法
    public int hashCode() {
        return name.hashCode(); // 返回id属性的哈希值
    }

    // 重写equals方法
    public boolean equals(Object obj) {
        if (this == obj) { // 判断是否是同一个对象
            return true; // 如果是,直接返回true
        }
        if (!(obj instanceof Person)) { // 判断对象是为Student类型
            return false; // 如果对象不是Student类型,返回false
        }
        Person p = (Person) obj; // 将对象强转为Student类型
        boolean b = this.name.equals(p.name); // 判断id值是否相同
        return b; // 返回判断结果
    }
}

public class Example2 {
    public static void main(String[] args) {
        HashSet hs = new HashSet(); // 创建HashSet对象
        Person p1 = new Person("18", "Jack"); // 创建Student对象
        Person p2 = new Person("19", "Rose");
        Person p3 = new Person("20", "Rose");
        hs.add(p1); // 向集合存入对象
        hs.add(p2);
        hs.add(p3);
        System.out.println(hs); // 打印集合中的元素
    }
}

(3)程序3源代码

package test6;

import java.util.*;

public class Example3 { // 创建TreeMap测试类
    public static void main(String[] args) {
        TreeMap tm = new TreeMap();// 传入一个自定义比较器
        tm.put("1", "Jack"); // 向集合存入学生的学号和姓名
        tm.put("2", "Rose");
        tm.put("5", "Lucy");
        tm.put("3", "Lucy");
        tm.put("4", "Rose");

        Set keySet = tm.keySet(); // 获取键的集合
        Iterator it = keySet.iterator(); // 获得迭代器对象
        while (it.hasNext()) {
            Object key = it.next(); // 获得一个键
            Object value = tm.get(key); // 获得键对应的值
            System.out.println(key + ":" + value);
        }
    }
}

(4)程序4源代码(如选做)

package test6;

import java.io.IOException;
import java.util.*;

public class Example4 {
    public static void main(String[] args) throws IOException {
        Scanner scanner = new Scanner(System.in);

        // 随机生成7个不重复的数
        int[] r = new int[7];
        boolean[] b = new boolean[31]; // 记录该数是否已经生成
        for (int i = 0; i < 7; i++) {
            int tem = (int) (Math.random() * 30) + 1;
            while (b[tem] == true)
                tem = (int) (Math.random() * 30) + 1;
            r[i] = tem;
            b[tem] = true;
        }
        // 输入7个数
        System.out.println("Please enter your numbers:");
        int[] in = new int[7];
        for (int i = 0; i < 7; i++) {
            in[i] = scanner.nextInt();
        }
        // 打印生成的7个随机数
        System.out.println("Random numbers:");
        for (int i = 0; i < 7; i++) {
            System.out.print(r[i] + " ");
        }
        System.out.println();
        // 打印你输入的7个数
        System.out.println("Your numbers:");
        for (int i = 0; i < 7; i++) {
            System.out.print(in[i] + " ");
        }
        System.out.println();
        // 打印相同的数
        int count = 0;
        System.out.println("The same numbers:");
        for (int i = 0; i < 7; i++)
            for (int j = 0; j < 7; j++) {
                if (in[i] == r[j]) {
                    System.out.println(in[i] + " ");
                    count++;
                }
            }
        switch (count) {
        case 1:
        case 2:
        case 3:
        case 4:
            System.out.println("Thanks!");
            break;
        case 5:
            System.out.println("Third prize!");
            break;
        case 6:
            System.out.println("Second prize!");
            break;
        case 7:
            System.out.println("First prize!");
            break;
        }
        System.out.println();
    }
}
掌握集合的概念、体系结构、分及使用场景 2)了解Set接口及主要实现HashSet、TreeSet) 3)了解List接口及主要实现(ArrayListLinkedList、Vector) 4)了解Map接口及主要实现(HashMap、TreeMap、HashTable) 二、实验内容及步骤 1、编写程序练习将以下5个Person的对象放在一个HashSet。 姓名:张三 身份证号:178880001 姓名:王五 身份证号:178880002 姓名:李四 身份证号:178880003 姓名:王五 身份证号:178880002 姓名:李四 身份证号:178880004 注意:因为Person是自定义,需要重写hashCode()方法和equals()方法,并规定只有姓名和身份证号都相等,则对象相等。 其计算哈希码的算法:(31 + ((name == null) ? 0 : name.hashCode()))*31 + id (注:name:Person对象的姓名,id:Person对象的身份证号) 主方法作如下测试: 1)创建一个可放置Person对象的HashSet; 2)依次添加上述5个对象到HashSet; 3)把集合的元素打印出来(使用迭代器Iterator) 2、编写程序练习List集合的基本使用: 1) 创建一个只能容纳String对象名为names的ArrayList集合; 2)按顺序往集合添加5个字符串对象:"张三"、"李四"、"王五"、"马六"、"赵七"; 3)对集合进行遍历,分别打印集合的每个元素的位置与内容; 4)打印集合的大小,然后删除集合的第3个元素,并显示删除元素的内容,然后再打印目前集合第3个元素的内容,并再次打印集合的大小。 3、编写程序练习Map集合的基本使用: 1)创建一个只能容纳String对象的person的HashMap集合; 2)往集合添加5个"键-值"对象: "id"-"1"; "name"-"张三"; "sex"-"男"; "age"-"25"; "hobby"-"爱学Java" 3)对集合进行遍历,分别打印集合的每个元素的键与值; 4)打印集合的大小,然后删除集合的键为age的元素,并显示删除元素的内容,并再次打印集合的大小。 四、思考题 1、集合List、Set、Map有哪些不同? 2、为什么使用集合框架,而尽可能少用数组作为存储结构? 3、如何使用TreeSet实现第一题?
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值