集合框架(练习题)

Key Point:

  • Collection 接口、Set接口、List接口基本操作
  • List接口及其实现类
  • Set接口及其实现类
  • 迭代遍历
  • Hash算法与hashCode方法
  • Comparable接口
  • Map接口及其实现类
  • 遍历Map
  • 泛型

问题:
1.填空

  • Collection接口的特点是元素是/对象/;
  • List接口的特点是元素/有/顺序,/可以/重复;
  • Set接口的特点是元素/无/顺序,/不可以/重复;
  • Map接口的特点是元素是/无序、无下标/,其中/值/可以重复,/键/不可以重复。

2.(List)有如下代码

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

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
		for(int i = 0 ;i<list.size();i++) {
			System.out.println(list.get(i));
		}
		System.out.println(list.toString());
	}

}
要求:
I.把//1处的代码补充完整,要求输出list中所有元素的内容
II.写出程序执行的结果
III.如果要把实现类由ArrayList换为LinkedList,应该改哪里?ArrayList和LinkedList使用上有什么区别?实现上有什么区别?
IV。如果要把实现类由ArrayList换为Vector,应该改哪里?ArrayList和Vector使用上有什么区别?实现上有什么区别?
//II.[Hello, Java, Learn, World]
//III.List list = new LinkedList()
 - ArrayList【重点】:
 数组结构实现,查询快、增删慢;
 JDK1.2版本,运行效率快、线程不安全。
 JDK8的ArrayList,实际初始长度是0
首次添加元素时,需要实际分配数组空间,执行数组扩容操作
真正向数组中插入数据,用的时候再创建,或再加载,有效的减低无用内存的空间。
可用于展示时——查询居多
   - LinkedList:
 链表结构实现,增删快,查询慢。空间存储不连续,线程不安全。
 常用于购物车——增删频繁
 // IV.List list = new Vector()
 - Vector:
 数组结构实现,查询快、增删慢;内存空间连续,初始大小10,java的最早集合。

3.(List)写出下面程序的运行结果

import java.util.ArrayList;
import java.util.List;
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

4.(Set,List)

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

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");
		list.remove("Hello");
		Set<String> set = new HashSet<String>();
		set.addAll(list);
		System.out.println(set.size());
	}
}
//编译运行正常,输出3

5.(List)已知有一个Worker类如下:

public class Worker {
	private int age;
	private String name;
	private double salary;
	public Worker() {}
	public Worker(int age, String name, double salary) {
		this.age = age;
		this.name = name;
		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");
	}
}
完成下面的要求
1) 创建一个 List,在 List 中增加三个工人,基本信息如下:
姓名 年龄 工资
zhang3 18 3000 
li4 25 3500 
wang5 22 3200 
2) 在 li4 之前插入一个工人,信息为:姓名:zhao6,年龄:24,工资 3300 
3) 删除 wang5 的信息
4) 利用 for 循环遍历,打印 List 中所有工人的信息
5) 利用迭代遍历,对 List 中所有的工人调用 work 方法。
6) 为 Worker 类添加 equals 方法
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class Worker {
	private int age;
	private String name;
	private double salary;
	public Worker() {}
	public Worker( String name,int age, double salary) {
		this.age = age;
		this.name = name;
		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");
	}
	        @Override
		    public String toString() {
		        return "name:" + name + "\tage:" + age + "\tsalary:" + salary;
		    }
		 
		    public boolean equals(Object obj) {
		        if (obj == this) {
		            return true;
		        }
		 
		        if (obj == null) {
		            return false;
		        }
		        if (obj.getClass() != this.getClass()) {
		            return false;
		        }
		        Worker obj_temp = (Worker) obj;
		        if ((this.name == obj_temp.name || obj_temp.name != null
		                && this.name.equals(obj_temp.name))
		                && (this.age == obj_temp.age)
		                && (this.salary == obj_temp.salary)) {
		            return true;
		        } else {
		            return false;
		        }
		 
		    }
		 
		    public static void main(String[] args) {
		        // 1) 创建一个 List,在 List 中增加三个工人,基本信息如下:
		        // 姓名 年龄 工资
		        // zhang3 18 3000
		        // li4 25 3500
		        // wang5 22 3200
		        List<Worker> list = new ArrayList<Worker>();
		        list.add(new Worker("zhang3", 18, 3000));
		        list.add(new Worker("li4", 25, 3500));
		        list.add(new Worker("wang5", 22, 3200));
		        // 2) 在 li4 之前插入一个工人,信息为:姓名:zhao6,年龄:24,工资 3300
		        list.add(2, new Worker("zhao6", 24, 3300));
		        // 3) 删除 wang5 的信息
		        list.remove(3);
		        // 4) 利用 for 循环遍历,打印 List 中所有工人的信息
		        for (int i = 0; i < list.size(); i++) {
		 
		        }
		        // 5) 利用迭代遍历,对 List 中所有的工人调用 work 方法。
		        Iterator<Worker> it = list.iterator();
		        while (it.hasNext()) {
		            System.out.println(it.next().toString());
		        }
		        // 6) 为 Worker 类添加 equals 方法--见上equals方法

	}
}

6.(Set,Hash算法)为上一题的Worker类,在添加完equals方法的基础上,添加一个hashCode方法。

public int hashCode(){
	//1
}
有几种写法:
I.return 0 ;
II.int result = 0;
	if(name != null)result = name.hashCode();
	result result+age;
III.return super.hashCode();
现在要把Worker类放入HashSet中,并希望在HashSet中没有重复元素,则下面说法正确的是:
A.三种写法都正确
B.I、II写法正确,II的效率更高
C.II法正确,I、II写法都不正确

B

7.(Set,Hash算法,方法覆盖)代码改错

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;
	}
	/*public*/ int hashCode() {
		return /*(int) (*/name.hashCode() + age + salary/*)*/;
	}
	public boolean equals(Worker w/*Object obj*/) {
		if(w.name ==/*.equals(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());
	}		
}

重写父类方法,访问修饰符的权限需要大于或等于父类,default默认修饰符的权限到非同包子类就无效了,即改为public或者protected合适

重写的equals方法中,传入参数应该为Object类型

set.add()在HashSet是无序的集合,不能在指定位置添加指定对象

8.(Set,Hash算法)在前面的Worker类基础上,为Worker类增加相应的方法,使得Worker放入HashSet中时,Set中没有重复元素。并编写相应的测试代码。

import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

public class Worker {
	private int age;
	private String name;
	private double salary;
	public Worker() {}
	public Worker( String name,int age, double salary) {
		this.age = age;
		this.name = name;
		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");
	}
	        @Override
		    public String toString() {
		        return "name:" + name + "\tage:" + age + "\tsalary:" + salary;
		    }
		    @Override
			public int hashCode() {
		    	return (int) (name.hashCode() + age + salary);
			}
			public boolean equals(Object obj) {
		        if (obj == this) {
		            return true;
		        }
		 
		        if (obj == null) {
		            return false;
		        }
		        if (obj.getClass() != this.getClass()) {
		            return false;
		        }
		        Worker obj_temp = (Worker) obj;
		        if ((this.name == obj_temp.name || obj_temp.name != null
		                && this.name.equals(obj_temp.name))
		                && (this.age == obj_temp.age)
		                && (this.salary == obj_temp.salary)) {
		            return true;
		        } else {
		            return false;
		        }
		 
		    }
		    public static void main(String[] args) {
		        // 1) 创建一个 workers,在 workers 中增加三个工人,基本信息如下:
		        // 姓名 年龄 工资
		        // zhang3 18 3000
		        // li4 25 3500
		        // wang5 22 3200
		        Set<Worker> workers = new HashSet<Worker>();
		        workers.add(new Worker("zhang3", 18, 3000));
		        workers.add(new Worker("li4", 25, 3500));
		        workers.add(new Worker("wang5", 22, 3200));
		       for(Worker ws:workers) {
		    	   System.out.println(ws.toString());
		       }	      
	}
}

9.(Map)关于下列Map接口中常见的方法:

I.put方法表示放入一个键值对,如果键已存在则/替换旧的/,如果 键不存在则/增加一个键值对/。
II.remove方法接收/一个/个参数,表示/删除一个键值对/。
III.get方法表示/通过键查找值/,get方法的参数表示/键名/,返回值表示/该键对应值/
IV.要想获得Map中所有的键,应该使用方法/keySet/,该方法返回值类型为/set/。
V.要想获得Map中所有的值,应该使用方法/values/,该方法返回值类型为/Collection/。
要想获得Map中的所有键值对的集合,应该使用方法entrySet,该方法返回一个Map.EntrySet类型所组成的Set。

10.(Map)利用Map,完成下面的功能:

从命令行读入一个字符串,表示一个年份,输出该年的世界杯冠军是哪支球队。
如果该年没有举办世界杯,则输出:没有举办世界杯。
附录:截止2009年,历届世界杯冠军、世界杯冠军以及对应的夺冠年份:
import java.util.HashMap;
import java.util.Scanner;

public class Map {
	public static void main(String[] args) {	
		HashMap<String,String> map = new HashMap<String,String>();
		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 sc = new Scanner(System.in);
		System.out.println("请输入一个年份:");
		String str = sc.nextLine();
			if(map.containsKey(str)==false) {
				System.out.println(str+"年没有举办世界杯");
			}else {
				System.out.println(str+"年夺冠的球队是:"+map.get(str));
			}		
	}
}

11.(Map)已知某学校的教学课程内容安排如下:

老师    课程
Tom   CoreJava
John   Oracle
Susan  Oracle
Jerry   JDBC
Jim     Unix
Kevin   JSP
Lucy    JSP
完成下列要求:
I.使用Map,以老师的名字作为键,教授的课程名作为值,表示上述课程安排。
II.增加了一位新老师Allen教JDBC
III.Lucy改为教CoreJava
IV.遍历Map,输出所有的老师及老师教授的课程
V.利用Map,输出所有教JSP的老师。
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

public class TestMap {
	public static void main(String[] args) {
		//I
		Map<String,String> map = new HashMap<String,String>();
		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");
		//II
		map.put("Allen","JDBC");
		//III
		map.put("Lucy","CoreJava");
		//IV
		Set<String> set = map.keySet();
		for(Object key:set) {
			System.out.println(key+"\t"+map.get(key));
		}
		//V
		if(map.containsValue("JSP")==true) {
			for(String k:map.keySet()) {
					if(map.get(k).equals("JSP")) {
						System.out.print("\t"+k+"="+"JSP");
				}
			}
		}
	}
}

12.(Set,HashSet,空指针)有下面代码

import java.util.HashSet;
import java.util.Set;
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 Exception in thread "main" java.lang.NullPointerException

13.(Map)在原有世界杯Map的基础上,增加如下功能:

读入一支球队的名字,输出该球队的年份列表。
例如:I.读入”巴西”,应当输出1958、1962、1970、1994、2002
II.读入“荷兰”,应当输出“没有获得过世界杯”。
import java.util.HashMap;
import java.util.Scanner;

public class Map {
	public static void main(String[] args) {	
		HashMap<String,String> map = new HashMap<String,String>();
		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 sc = new Scanner(System.in);
		System.out.println("请输入一个年份:");
		String str = sc.nextLine();
			if(map.containsKey(str)==false) {
				System.out.println(str+"年没有举办世界杯");
			}else {
				System.out.println(str+"年夺冠的球队是:"+map.get(str));
			}	
			
		System.out.println("请输入夺冠球队:");
		String str1 = sc.nextLine();
		if(map.containsValue(str1)==false) {
			System.out.println(str1+"队没有获得过冠军");
		}else {
			System.out.println(str1+"队的夺冠年份是:");
			for(String k:map.keySet()) {
				if(map.get(k).equals(str1)) {
					System.out.print("\t"+k);
				}
			}
		}
	}
}

14.(Map)给定一个字符串,请输出该字符串由哪些字符组成,每个字符出现几次?

import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;

public class NumberCount {

	public static void main(String[] args) {
		
		Scanner sc = new Scanner(System.in);
		System.out.print("请输入一个字符串:");
		String str = sc.nextLine();
		//字符串转数字
		char[] chars = str.toCharArray();
		Map<Character,Integer>map = new HashMap<Character,Integer>();
		//遍历字符数组
		for(char c:chars) {
			if(!map.containsKey(c)) {//字母首次出现记录1
				map.put(c,1);
			}else {
				map.put(c,map.get(c)+1);//每出现一次字符就覆盖其value值+1
			}
		}
		//打印结果
		for(Character key:map.keySet()) {
			System.out.println(key+"字符在字符串中出现了"+map.get(key)+"次");
		}
	}
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章