question12
Question12_集合
1、填空
Collection 接口的特点是元素是__;
List 接口的特点是元素__(有|无)顺序,__(可以|不可以)重复;
Set接口的特点是元素__(有|无)顺序,__(可以|不可以)重复;
Map接口的特点是元素是__,其中_可以重复,__ 不可以重复。
对象的集合
有,可以
无,不可以
键值对 值 键
2、有如下代码
import java.util.*;
public class TestList {
public static void main(String args[]) {
List<String> list = new ArrayList<String>();
list.add("Hello");
list.add("World");
list.add(1, "Learn");
list.add(1, "Java");
printList(list);
}
public static void printList(List list) {
//1
}
}
要求:
2.1 把//1处的代码补充完整,要求输出list 中所有元素的内容。
2.2 写出程序执行的结果。
2.3 如果要把实现类由ArrayList换为LinkedList,应该改哪里?ArrayList和LinkedList使用上有什么区别?实现上有什么区别?
2.4 如果要把实现类由ArrayList换为Vector,应该改哪里?ArrayList和Vector使用上有什么区别?实现上有什么区别?
for(Object o : list){
System.out.println(o);
}
Hello Java Learn World
List要改为LinkedList
使用上:没什么区别
实现上:ArrayList底层是数组实现,查询快,增删慢。LinkedList底层是链表实现,增删快,查询慢
List改为Vector
使用上:没什么区别
实现上:Vector也是数组实现,运行效率慢,线程安全
3、写出下面程序的运行结果
import java.util.*;
public class TestList {
public static void main(String args[]) {
List<String> list = new ArrayList<String>();
list.add("Hello");
list.add("World");
list.add("Hello");
list.add("Learn");
list.remove("Hello");
list.remove(0);
for (int i = 0; i < list.size(); i++) {
System.out.println(list.get(i));
}
}
}
Hello Learn
在调用第一个remove方法时,会删掉遇到的第一个“Hello”对象,List中剩下的元素为:World Hello Learn
在调用第二个remove方法时,会删掉下标为0的元素。List中剩下的元素为:Hello Learn
4、选择正确答案
import java.util.*;
public class TestListSet {
public static void main(String args[]) {
List<String> list = new ArrayList<String>();
list.add("Hello");
list.add("Learn");
list.add("Hello");
list.add("Welcome");
Set<String> set = new HashSet<String>();
set.addAll(list);
System.out.println(set.size());
}
}
A. 编译不通过。
B. 编译通过,运行时异常。
C. 编译运行都正常,输出3。
D. 编译运行都正常,输出4。
C
该程序主要是调用List的addAll方法。调用该方法时,会把List中的所有元素都加入Set中。要注意的是,重复元素不会被加入
5、已知有一个Worker 类如下
public class Worker {
private int age;
private String name;
private double salary;
public Worker() {
}
public Worker(String name, int age, double salary) {
this.name = name;
this.age = age;
this.salary = salary;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getSalary() {
return salary;
}
public void setSalary(double salary) {
this.salary = salary;
}
public void work() {
System.out.println(name + "work");
}
}
完成下面的要求:
5.1 创建一个List,在List中增加三个工人,基本信息如下
| 姓名 | 年龄 | 工资 |
|---|---|---|
| zhang3 | 18 | 3000 |
| li4 | 25 | 3500 |
| wang5 | 22 | 3200 |
5.2 在li4之前插入一个工人,信息为:姓名:zhao6,年龄:24,工资3300
5.3 删除wang5的信息。
5.4 利用for循环遍历,打印List中所有工人的信息。
5.5 利用for-each遍历,对List中所有的工人调用work方法。
5.6 为Worker类添加equals方法。
import java.util.Objects;
public class Worker {
private String name;
private int age;
private double salary;
public Worker() {
super();
}
public Worker(String name, int age, double salary) {
super();
this.name = name;
this.age = age;
this.salary = salary;
}
public void setName(String name) {
this.name = name;
}
public double getSalary() {
return salary;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setSalary(double salary) {
this.salary = salary;
}
public void work() {
System.out.println(name + "work");
}
//重写toString方法
@Override
public String toString() {
return "Worker [name=" + name + ", age=" + age + ", salary=" + salary + "]";
}
//重写equals方法
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Worker other = (Worker) obj;
return age == other.age && Objects.equals(name, other.name)
&& Double.doubleToLongBits(salary) == Double.doubleToLongBits(other.salary);
}
}
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
public class ListWork {
public static void main(String[] args) {
//创建集合
List<Worker> workers = new ArrayList<Worker>();
//增加三名工人
Worker w1 = new Worker("zhang3",18,3000);
Worker w2 = new Worker("li4",25,3500);
Worker w3 = new Worker("wang5",22,3200);
workers.add(w1);
workers.add(w2);
workers.add(w3);
System.out.println("工人有:"+workers.size()+"个,分别是:");
System.out.println(workers);
//在list4前插入工人
workers.add(1, new Worker("zhao6",24,3300));
System.out.println("工人有:"+workers.size()+"个,分别是:");
System.out.println(workers);
//删除wang5的信息
workers.remove(w3);
System.out.println("工人有:"+workers.size()+"个,分别是:");
System.out.println(workers);
//通过循环遍历,打印所有工人信息
//通过for循环
System.out.println("通过for循环打印工人信息");
for (int i = 0; i < workers.size(); i++) {
System.out.println(workers.get(i));
}
System.out.println("通过增强型for循环打印工人信息");
for (Worker worker : workers) {
System.out.println(worker);
}
System.out.println("通过迭代器循环打印工人信息");
Iterator<Worker> iterator = workers.iterator();
while (iterator.hasNext()) {
Worker worker = (Worker) iterator.next();
System.out.println(worker);
}
System.out.println("通过列表迭代器循环打印工人信息");
ListIterator<Worker> iterator2 = workers.listIterator();
while (iterator2.hasNext()) {
System.out.println("下标是:"+iterator2.nextIndex()+",工人信息是:"+iterator2.next());
}
System.out.println("通过列表迭代器逆序循环打印工人信息");
while (iterator2.hasPrevious()) {
System.out.println("下标是:"+iterator2.nextIndex()+",工人信息是:"+iterator2.previous());
}
//利用for-each遍历,对List中所有的工人调用work方法
System.out.println("利用for-each遍历,对List中所有的工人调用work方法");
for (Worker worker : workers) {
worker.work();
}
}
}
6、为上一题的Worker类,在添加完equals方法的基础上,添加一个hashCode方法。
public int hashCode(){
//1
}
如下:
public int hashCode(){
int result = 0;
result += (int)(age + salary);
if (name != null) result += name.hashCode();
if (address != null) result += this.address.hashCode();
return result;
}
I.
return 0;
II.
int result = 0;
if (name != null) result = name.hashCode();
return result + age;
III.
return super.hashCode();
现在要把Worker类放入HashSet中,并希望在HashSet中没有重复元素,则下面说法正确的是:
A. 三种写法都正确
B. I、II写法正确,II的效率更高
C. II写法正确,I、III写法都不正确
B
hashCode正确性要求:相同对象返回相同哈希码。这方面I、II都满足要求
hashCode效率要求:不同对象返回的哈希码尽量不同。这方面II做的更好,用到了Worker类的两个属性,因此效率更高
7、代码改错
import java.util.*;
class Worker {
String name;
int age;
double salary;
public Worker() {
}
public Worker(String name, int age, double salary) {
this.name = name;
this.age = age;
this.salary = salary;
}
int hashCode() {
return name.hashCode() + age + salary;
}
public boolean equals(Worker w) {
if (w.name == name && w.salary == salary && w.age == age) {
return true;
} else {
return false;
}
}
}
public class TestWorker {
public static void main(String args[]) {
Set<Worker> set = new HashSet<Worker>();
set.add(new Worker("tom", 18, 2000));
set.add(new Worker("tom", 18, 2000));
set.add(0, new Worker("jerry", 18, 2000));
System.out.println(set.size());
}
}
改错
import java.util.Objects;
public class Worker {
String name;
int age;
double salary;
public Worker() {
}
public Worker(String name, int age, double salary) {
this.name = name;
this.age = age;
this.salary = salary;
}
//重写hashCode方法和equals方法
@Override
public int hashCode() {
//返回值int类型,强转
return (int) (name.hashCode() + age + salary);
}
@Override
public boolean equals(Object obj) {
//从写equals方法
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Worker other = (Worker) obj;
return age == other.age && Objects.equals(name, other.name)
&& Double.doubleToLongBits(salary) == Double.doubleToLongBits(other.salary);
}
}
public class TestWorker {
public static void main(String args[]) {
Set<Worker> set = new HashSet<Worker>();
set.add(new Worker("tom", 18, 2000));
set.add(new Worker("tom", 18, 2000));
//Set 接口中没有定义带下标的add方法
set.add(new Worker("jerry", 18, 2000));
System.out.println(set.size());
}
}
8、在前面的Worker类基础上,为Worker类增加相应的方法,使得Worker放入HashSet中时,Set中没有重复元素。并编写相应的测试代码
重写hashCode和equals方法
9、关于下列Map接口中常见的方法(填空)
9.1 put方法表示放入一个键值对,如果键已存在则_____,如果键不存在则_____。
9.2 remove方法接受_____个参数,表示_____。
9.3 get方法表示_____,get 方法的参数表示_____,返回值表示_____。
9.4 要想获得Map中所有的键,应该使用方法_____,该方法返回值类型为_____。
9.5 要想获得Map中所有的值,应该使用方法_____,该方法返回值类型为_____。
替换值 插入
1 移除指定映射
获取值 键 值
keySet() Collection
values() Set
10、利用Map,完成下面的功能
从命令行读入一个字符串,表示一个年份,输出该年的世界杯冠军是哪支球队。如果该年没有举办世界杯,则输出:没有举办世界杯
附录:截止2009年,历届世界杯冠军、世界杯冠军以及对应的夺冠年份
| 届数 | 年份 | 冠军 |
|---|---|---|
| 18 | 2006 | 意大利 |
| 17 | 2002 | 巴西 |
| 16 | 1998 | 法国 |
| 15 | 1994 | 巴西 |
| 14 | 1990 | 德国 |
| 13 | 1986 | 阿根廷 |
| 12 | 1982 | 意大利 |
| 11 | 1978 | 阿根廷 |
| 10 | 1974 | 德国 |
| 9 | 1970 | 巴西 |
| 8 | 1966 | 英格兰 |
| 7 | 1962 | 巴西 |
| 6 | 1958 | 巴西 |
| 5 | 1954 | 德国 |
| 4 | 1950 | 乌拉圭 |
| 3 | 1938 | 意大利 |
| 2 | 1934 | 意大利 |
| 1 | 1930 | 乌拉圭 |
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;
public class WorldCup extends Thread{
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
while (true) {
System.out.println("=====【世界杯冠军查询】=====");
System.out.println("=========【请输入】=========");
System.out.println("===【1】开始查询【0】退出===");
int choice = input.nextInt();
switch (choice) {
case 0:
exit();
System.out.println("退出成功...");
return;
case 1:
search();
break;
default:
System.out.println("请输入正确的数字");
break;
}
}
}
public static void exit() {
WorldCup exit = new WorldCup();
try {
exit.sleep(300);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public static void search() {
//创建集合
Map map = new HashMap();
//添加元素
map.put(1930, "乌拉圭");
map.put(1934, "意大利");
map.put(1938, "意大利");
map.put(1950, "乌拉圭");
map.put(1954, "德国");
map.put(1958, "巴西");
map.put(1962, "巴西");
map.put(1966, "英格兰");
map.put(1970, "巴西");
map.put(1974, "德国");
map.put(1978, "阿根廷");
map.put(1982, "意大利");
map.put(1986, "阿根廷");
map.put(1990, "德国");
map.put(1994, "巴西");
map.put(1998, "法国");
map.put(2002, "巴西");
map.put(2006, "意大利");
Scanner input = new Scanner(System.in);
System.out.println("请输入年份:");
int year = input.nextInt();
if (map.containsKey(year)) {
System.out.println(year+"年,世界杯冠军是:"+map.get(year));
}else {
System.out.println(year+"年,没有举行世界杯!");
}
}
}
11、已知某学校的教学课程内容安排如下
| 老师 | 课程 |
|---|---|
| Tom | CoreJava |
| John | Oracle |
| Susan | Oracle |
| Jerry | JDBC |
| Jim | Unix |
| Kevin | JSP |
| Lucy | JSP |
完成下列要求:
11.1 使用Map,以老师的名字作为键,教授的课程名作为值,表示上述课程安排。
11.2 增加了一位新老师Allen教JDBC。
11.3 Lucy改为教CoreJava。
11.4 遍历Map,输出所有的老师及老师教授的课程。
11.5 利用Map,输出所有教JSP的老师。
mport java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
public class Course {
public static void main(String[] args) {
Map map = new HashMap();
map.put("Tom", "CoreJava");
map.put("John", "Oracle");
map.put("Susan", "Oracle");
map.put("Jerry", "JDBC");
map.put("Jim", "Unix");
map.put("Kevin", "JSP");
map.put("Lucy", "JSP");
//增加了一位新老师Allen教JDBC
map.put("Allen", "JDBC");
//Lucy改为教CoreJava
map.put("Lucy", "CoreJava");
//遍历
Set set = map.keySet();
Iterator it = set.iterator();
while (it.hasNext()) {
Object key = it.next();
System.out.println(key+"----"+map.get(key));
}
//输出所有教JSP的老师
Iterator it1 = set.iterator();
while (it1.hasNext()) {
Object next = it1.next();
if (map.get(next).equals("JSP")) {
System.out.println(next);
}
}
}
}
12、有下面代码
import java.util.*;
class Student {
int age;
String name;
public Student() {
}
public Student(String name, int age) {
this.name = name;
this.age = age;
}
public int hashCode() {
return name.hashCode() + age;
}
public boolean equals(Object o) {
if (o == null)
return false;
if (o == this)
return true;
if (o.getClass() != this.getClass())
return false;
Student stu = (Student) o;
if (stu.name.equals(name) && stu.age == age)
return true;
else
return false;
}
}
public class TestHashSet {
public static void main(String args[]) {
Set<Student> set = new HashSet<Student>();
Student stu1 = new Student();
Student stu2 = new Student("Tom", 18);
Student stu3 = new Student("Tom", 18);
set.add(stu1);
set.add(stu2);
set.add(stu3);
System.out.println(set.size());
}
}
下列说法正确的是:
A. 编译错误。
B. 编译正确,运行时异常。
C. 编译运行都正确,输出结果为3。
D. 编译运行都正确,输出结果为2。
B
当把一个Student对象放到HashSet中时,会调用该对象的hashCode方法。
Student类覆盖了hashCode方法,会调用name属性的hashCode方法。
对于stu1对象而言,由于调用了默认构造函数,其name属性为null。当调用name属性的hashCode时,会出现NullPointerException异常
13、在原有世界杯Map的基础上,增加如下功能
读入一支球队的名字,输出该球队夺冠的年份列表。
例如:
13.1 读入“巴西”,应当输出1958、1962、1970、1994、2002。
13.2 读入“荷兰”,应当输出”没有获得过世界杯”。
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Scanner;
import java.util.Set;
public class WorldCup2 extends Thread{
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
while (true) {
System.out.println("=====【世界杯冠军查询】=====");
System.out.println("=========【请输入】=========");
System.out.println("===【1】输入国家开始查询【0】退出===");
int choice = input.nextInt();
switch (choice) {
case 0:
exit();
System.out.println("退出成功...");
return;
case 1:
search();
break;
default:
System.out.println("请输入正确的数字");
break;
}
}
}
public static void exit() {
WorldCup2 exit = new WorldCup2();
try {
exit.sleep(300);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public static void search() {
//创建集合
Map map = new HashMap();
//添加元素
map.put(1930, "乌拉圭");
map.put(1934, "意大利");
map.put(1938, "意大利");
map.put(1950, "乌拉圭");
map.put(1954, "德国");
map.put(1958, "巴西");
map.put(1962, "巴西");
map.put(1966, "英格兰");
map.put(1970, "巴西");
map.put(1974, "德国");
map.put(1978, "阿根廷");
map.put(1982, "意大利");
map.put(1986, "阿根廷");
map.put(1990, "德国");
map.put(1994, "巴西");
map.put(1998, "法国");
map.put(2002, "巴西");
map.put(2006, "意大利");
Scanner input = new Scanner(System.in);
System.out.println("请输入国家:");
String country = input.next();
if (map.containsValue(country)) {
Set keySet = map.keySet();
Iterator iterator = keySet.iterator();
while(iterator.hasNext()){
Object next = iterator.next();
if(map.get(next).equals(country)) {
System.out.println(country+"获得世界杯冠军的年份是:"+next);
}
}
}else {
System.out.println(country+"没有获得过世界杯...");
}
}
}
14、给定一个字符串,请输出该字符串由哪些字符组成,每个字符出现几次?
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;
import java.util.Set;
public class StringDemo {
public static void main(String[] args) {
System.out.println("请输入字符串:");
Scanner sc = new Scanner(System.in);
String s = sc.next();
// 键:字符 值:次数
Map<Character, Integer> map = new HashMap<Character, Integer>();
for (int i = 0; i < s.length(); i++) {
// 获取字符
char c = s.charAt(i);
// 判断
if (map.containsKey(c)) {
// 拿到值
int m = map.get(c);
// 值++
map.put(c, m + 1);
} else {
map.put(c, 1);
}
}
// 遍历
Set<Character> keySet = map.keySet();
for (Character character : keySet) {
int count = map.get(character);
System.out.println("字符:" + character + ",出现的次数为:" + count);
}
}
}

浙公网安备 33010602011771号