Java程序设计实验6 | 集合类
*本文是博主对Java各种实验的再整理与详解,除了代码部分和解析部分,一些题目还增加了拓展部分(⭐)。拓展部分不是实验报告中原有的内容,而是博主本人自己的补充,以方便大家额外学习、参考。
(解析部分还没加,过阵子补)
目录
一、实验目的
二、实验内容
1、将下列数据:“hello”、123、6.9、“hello”、“”、“Hello”、StringBuffer s=new StringBuffer(“hello”)中的s,添加到一个ArrayList对象中。
2、使用ArrayList集合,向集合中添加10个整数,并使用Iterator遍历该集合,并查找键盘输入的元素。
3、分别利用Arraylist和Set随机生成十个不重复的随机整数,随机整数范围为350到450。
4、集合中不容许有重复的对象,对于多个重复对象只能添加一次。例如在HashSet集合中添加三个Person对象,把姓名相同的人当做同一个人,虽然可以添加多次但集合里只保留一个,但是这对类的设计是有要求的,假设Person类中只包含name和age属性,则需要重写hashCode()方法和equals()方法,如果两个对象的name相同,则hashCode()方法的返回值相同,equals()方法返回true。
5、编写程序将一组学生对象的姓名和成绩存入到一个树集(TreeSet)中。
6、编写一个程序,读取个数不定的整数,然后查找其中出现频率最高的数字。要求通过键盘输入数据,当输入为0时,表示结束输入。如: 如果输入的数据是2 3 40 3 54 -3 3 3 2 0,那么数字3的出现频率是最高的。如果出现频率最高的数字不是一个而是多个,则应该将它们全部输出。例如当数据是9 30 3 9 3 2 4时,3和9都出现了两次,3和9都应该输出。
7、选择合适的Map集合保存5个用户的用户名和密码,然后将这些键值对打印出来。
8、(选做)统计字符串中每个单词出现的次数,使用HashMap来实现。例如:“Today, We have a class of java, as we kown, java is an object oriented programming language, and java is fun! wish you enjoy it!”.
9、(选做)500个人围成一个圈,从1开始报数,数到3的倍数的人离开圈子,循环往复,直到最后圈子只剩下一人为止,求剩下的人原来在圈子的位置。
三、实验总结
一、实验目的
1、掌握容器类的层次结构;
2、掌握Collection接口和List接口的常用方法;
3、掌握Iterator接口的使用方式;
4、掌握Set接口和hashCode的使用方式;
5、掌握Map接口的使用方式。
二、实验内容
1、将下列数据:“hello”、123、6.9、“hello”、“”、“Hello”、StringBuffer s=new StringBuffer(“hello”)中的s,添加到一个ArrayList对象中。
• 将ArrayList中的所有元素打印输出。
• 查找元素“hello”。
• 删除指定的元素“hello”。
• 将元素123替换为1000。
源代码:
import java.util.ArrayList;
public class S6_1 {
public static void main(String[] args) {
// 创建ArrayList对象
ArrayList<Object> list = new ArrayList<>();
// 添加数据到ArrayList
list.add("hello");
list.add(123);
list.add(6.9);
list.add("hello");
list.add("");
list.add("Hello");
StringBuffer s = new StringBuffer("hello");
list.add(s);
// 打印输出所有元素
System.out.println("ArrayList中的所有元素为:");
for (Object element : list) {
System.out.print(element + ",");
}
System.out.println("\n========================");
// 查找元素“hello”
boolean found = list.contains("hello");
if (found) {
System.out.println("找到元素\"hello\"");
} else {
System.out.println("未找到元素\"hello\"");
}
System.out.println("\n========================");
// 删除指定的元素“hello”
list.remove("hello");
System.out.println("删除元素\"hello\"后的ArrayList:");
for (Object element : list) {
System.out.println(element + ",");
}
System.out.println("\n========================");
// 将元素123替换为1000
int index123 = list.indexOf(123);
if (index123 != -1) {
list.set(index123, 1000);
System.out.println("将元素123替换为1000后的ArrayList:");
for (Object element : list) {
System.out.println(element);
}
} else {
System.out.println("未找到元素123");
}
}
}
列出测试数据和实验结果截图:
2、使用ArrayList集合,向集合中添加10个整数,并使用Iterator遍历该集合,并查找键盘输入的元素。
提示:
• 使用add()方法将元素添加到ArrayList集合中。
• 调用集合的iterator()方法获得Iterator对象,并调用Iterator的hasNext()和next()方法,迭代出集合中的所有元素,完成查找功能,并将重复的元素删除。
源代码:
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Random;
import java.util.Scanner;
public class S6_2 {
public static void main(String[] args) {
ArrayList<Integer> list = new ArrayList<>();
// 1-向集合中添加10个随机整数
for (int i = 0; i < 10; i++) {
list.add(new Random().nextInt(10));
}
System.out.println(list);
// 2-使用Iterator遍历集合并查找键盘输入的元素
Iterator<Integer> iterator = list.iterator();
Scanner reader = new Scanner(System.in);
System.out.print("请输入要查找的整数:");
int input = reader.nextInt();
// 3-去重
int count = 0;
while (iterator.hasNext()) {
int current = iterator.next();
if (current == input) {
count++;
System.out.println("找到第" + count + "个元素 " + input);
if(count > 1)
iterator.remove(); // 删除重复的元素
}
}
// 打印删除重复元素后的集合
System.out.println("删除重复元素后的ArrayList:");
System.out.println(list);
}
}
列出测试数据和实验结果截图:
3、分别利用Arraylist和Set随机生成十个不重复的随机整数,随机整数范围为350到450。
源代码:
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Random;
import java.util.Set;
public class S6_3 {
public static void main(String[] args) {
// 使用 ArrayList 生成不重复的随机整数
ArrayList<Integer> arrayList = generateRandomNumbersArrayList();
System.out.println("ArrayList中的随机数:");
System.out.println(arrayList);
// 使用 Set 生成不重复的随机整数
Set<Integer> set = generateRandomNumbersSet();
System.out.println("Set中的随机数:");
System.out.println(set);
}
// 生成 ArrayList 中的随机整数
private static ArrayList<Integer> generateRandomNumbersArrayList() {
ArrayList<Integer> arrayList = new ArrayList<>();
Random random = new Random();
while (arrayList.size() < 10) {
int randomNumber = random.nextInt(101) + 350; // 生成350到450的随机数
if (!arrayList.contains(randomNumber)) {
arrayList.add(randomNumber);
}
}
return arrayList;
}
// 生成 Set 中的随机整数
private static Set<Integer> generateRandomNumbersSet() {
Set<Integer> set = new HashSet<>();
Random random = new Random();
while (set.size() < 10) {
int randomNumber = random.nextInt(101) + 350; // 生成350到450的随机数
set.add(randomNumber); //因为Set内置去重功能,故添加后无需判断
}
return set;
}
}
列出测试数据和实验结果截图:
4、集合中不容许有重复的对象,对于多个重复对象只能添加一次。例如在HashSet集合中添加三个Person对象,把姓名相同的人当做同一个人,虽然可以添加多次但集合里只保留一个,但是这对类的设计是有要求的,假设Person类中只包含name和age属性,则需要重写hashCode()方法和equals()方法,如果两个对象的name相同,则hashCode()方法的返回值相同,equals()方法返回true。
源代码:
import java.util.HashSet;
import java.util.Objects;
class Person {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
// Getters and setters
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
// 重写 hashCode 方法
@Override
public int hashCode() {
return Objects.hash(name);
}
// 重写 equals 方法
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null || getClass() != obj.getClass()) {
return false;
}
Person person = (Person) obj;
return Objects.equals(name, person.name);
}
}
public class S6_4 {
public static void main(String[] args) {
HashSet<Person> personSet = new HashSet<>();
// 添加三个 Person 对象,其中两个 name 相同
Person person1 = new Person("碳基肥宅", 25);
Person person2 = new Person("热心网友wyd", 30);
Person person3 = new Person("碳基肥宅", 28);
personSet.add(person1);
personSet.add(person2);
personSet.add(person3);
// 打印 HashSet 中的元素数量
System.out.println("HashSet 中的元素数量:" + personSet.size());
for (Person person : personSet) {
System.out.println(person.getName() + " : " + person.getAge());
}
}
}
列出测试数据和实验结果截图:
5、编写程序将一组学生对象的姓名和成绩存入到一个树集(TreeSet)中。
完成以下要求:
• 使得按照成绩自动降序排列,并输出排序的结果。
源代码:
import java.util.Comparator;
import java.util.TreeSet;
// 学生类
class Student {
private String name;
private int score;
public Student(String name, int score) {
this.name = name;
this.score = score;
}
// Getters
public String getName() {
return name;
}
public int getScore() {
return score;
}
@Override
public String toString() {
return name + " : " + score;
}
}
public class S6_5 {
public static void main(String[] args) {
// 创建 TreeSet 并指定降序排序的比较器
TreeSet<Student> studentSet = new TreeSet<>(Comparator.comparingInt(Student::getScore).reversed());
// 向 TreeSet 中添加学生对象
studentSet.add(new Student("碳基肥宅", 85));
studentSet.add(new Student("热心网友wyd", 75));
studentSet.add(new Student("叮当同学", 92));
studentSet.add(new Student("朵拉", 68));
// 输出排序结果(按照成绩降序)
System.out.println("按照成绩降序排列的学生信息:");
for (Student student : studentSet) {
System.out.println(student);
}
}
}
列出测试数据和实验结果截图:
6、编写一个程序,读取个数不定的整数,然后查找其中出现频率最高的数字。要求通过键盘输入数据,当输入为0时,表示结束输入。如: 如果输入的数据是2 3 40 3 54 -3 3 3 2 0,那么数字3的出现频率是最高的。如果出现频率最高的数字不是一个而是多个,则应该将它们全部输出。例如当数据是9 30 3 9 3 2 4时,3和9都出现了两次,3和9都应该输出。
提示:可以利用集合的元素不能重复这一特性。
源代码:
import java.util.*;
public class S6_6 {
public static void main(String[] args) {
Scanner reader = new Scanner(System.in);
Map<Integer, Integer> map = new HashMap<>();
System.out.println("请输入整数(输入0结束输入):");
int input;
while ((input = reader.nextInt()) != 0) {
map.put(input, map.getOrDefault(input, 0) + 1);
}
// 找出最大频率
int maxFrequency = Collections.max(map.values());
// 输出出现最大频率的数字
System.out.println("出现频率最高的数字是:");
for (Map.Entry<Integer, Integer> entry : map.entrySet()) {
if (entry.getValue() == maxFrequency) {
System.out.print(entry.getKey());
}
}
}
}
列出测试数据和实验结果截图:
也可以用PriorityQueue完成,感兴趣的朋友可以试试,具体的实现过阵子补在这里。
7、选择合适的Map集合保存5个用户的用户名和密码,然后将这些键值对打印出来。
源代码:
import java.util.HashMap;
import java.util.Map;
public class S6_7 {
public static void main(String[] args) {
// 创建一个 HashMap 来保存用户名和密码
Map<String, String> userCredentials = new HashMap<>();
// 添加用户的用户名和密码
userCredentials.put("user1", "password1");
userCredentials.put("user2", "password2");
userCredentials.put("user3", "password3");
userCredentials.put("user4", "password4");
userCredentials.put("user5", "password5");
// 打印用户名和密码的键值对
System.out.println("用户名和密码的键值对:");
for (Map.Entry<String, String> entry : userCredentials.entrySet()) {
System.out.println("用户名: " + entry.getKey() + ", 密码: " + entry.getValue());
}
}
}
列出测试数据和实验结果截图:
8、(选做)统计字符串中每个单词出现的次数,使用HashMap来实现。例如:“Today, We have a class of java, as we kown, java is an object oriented programming language, and java is fun! wish you enjoy it!”.
统计结果存储成以下形式:
a-->1
an-->1
and-->1
as-->1……
is-->2
提示:使用String.split(("[ \n\t\r.,;:!?()]")方法进行分词。
源代码:
import java.util.HashMap;
import java.util.Map;
public class S6_8 {
public static void main(String[] args) {
String text = "Today, We have a class of java, as we kown, java is an object oriented programming language, and java is fun! wish you enjoy it!";
// 去除标点符号并分割字符串为单词
String[] words = text.split("[ \n\t\r.,;:!?()]");
// 创建 HashMap 来存储单词及其出现的次数
Map<String, Integer> wordCount = new HashMap<>();
// 统计单词出现的次数
for (String word : words) {
word = word.toLowerCase(); // 将单词转换为小写
if (!word.isEmpty()) {
wordCount.put(word, wordCount.getOrDefault(word, 0) + 1);
}
}
// 打印每个单词及其出现的次数
System.out.println("每个单词出现的次数:");
for (Map.Entry<String, Integer> entry : wordCount.entrySet()) {
System.out.println(entry.getKey() + "-->" + entry.getValue());
}
}
}
列出测试数据和实验结果截图:
9、(选做)500个人围成一个圈,从1开始报数,数到3的倍数的人离开圈子,循环往复,直到最后圈子只剩下一人为止,求剩下的人原来在圈子的位置。
提示:可以使用集合(ArrayList)或队列(Deque)实现。
源代码:
这个问题其实是著名的约瑟夫问题(Josephus problem),可以用递推的方式求解。
以下是使用队列(Deque
)来模拟这个问题并求解最后剩下的人在原来圈子的位置:
import java.util.ArrayDeque;
import java.util.Deque;
public class S6_9 {
public static void main(String[] args) {
int totalPeople = 500;
int count = 3;
Deque<Integer> circle = new ArrayDeque<>();
// 初始化圈子,编号从1到500
for (int i = 1; i <= totalPeople; i++) {
circle.addLast(i);
}
// 开始循环报数,直到圈子中只剩一个人为止
while (circle.size() > 1) {
for (int i = 0; i < count - 1; i++) {
int person = circle.removeFirst();
circle.addLast(person);
}
circle.removeFirst(); // 数到3的倍数的人离开圈子
}
// 打印最后剩下的人在原来圈子的位置
System.out.println("最后剩下的人在原来圈子的位置是:" + circle.peek());
}
}
列出测试数据和实验结果截图:
三、实验总结
在这个实验中我学到了很多关于集合类、循环和算法的知识,这些练习加深了我对集合、字符串处理和算法设计的理解。通过这些题目,我学会了:
- 掌握了ArrayList、HashSet、TreeSet、HashMap 等集合类的基本操作,包括添加、删除、遍历和使用键值对等。
- 学会了使用 split() 方法分割字符串,以及在字符串中搜索特定的内容。
- 理解了为了在集合中正确比较和存储自定义对象,需要重写 hashCode() 和 equals() 方法的重要性。
- 解决了一些经典问题,比如约瑟夫问题,提高了算法思维和编码能力。