集合框架(練習題)

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)+"次");
		}
	}
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章