前言:
本次我在每个实验题下面都简单的写了一下思路解析,希望同学们先看看思路解析后尽量尝试自己做一下,不要只是简单的Ctrl c + Ctrl v,如果有疑惑的地方也欢迎找我来探讨呀🎈。
实验一:
1、将下列数据:“hello”、123、6.9、“hello”、“”、“Hello”、StringBuffer s=new StringBuffer(“hello”)中的s,添加到一个ArrayList对象中。。
• 将ArrayList中的所有元素打印输出。
• 查找元素“hello”。
• 删除指定的元素“hello”。
• 将元素123替换为1000。
思路解析:
- 可以看出本题主要考察ArrayList的常用方法
- 遍历的三种方式:普通for循环;增强for循环;iterator迭代
- 使用for循环查找元素下标,但是需要注意集合中可能不止一个元素,即符合的下标不为一,我们可以再创建一个集合存储下标
- ArrayList的remove方法,删除元素
- ArrayList的set方法,修改元素
源代码:
public static void main(String[] args) {
ArrayList<Object> list = new 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);
//将ArrayList中的所有元素打印输出。
//这里使用集合的迭代器方法遍历输出,同样可以使用for循环与增强for循环
System.out.print("遍历list: ");
Iterator<Object> iterator = list.iterator();
while (iterator.hasNext()){
System.out.print(iterator.next()+" ");
}
System.out.println();
/*查找元素“hello”。
因为不太理解题目查找的意思,姑且理解为寻找相应元素的下标
我这里新建了一个集合index,通过遍历list找到"hello"元素并将索引添加到index
这里需要注意的是StringBuffer类与String不同,所以list中添加的s并不属于查找范围
*/
ArrayList<Integer> index = new ArrayList<>();
for(int i =0;i<list.size();i++){
if(list.get(i).equals("hello")){
index.add(i);
}
}
System.out.println("hello在list中的下标为:"+index);
//删除指定的元素“hello”。直接用集合类的remove方法即可
for(int i = 0;i<list.size();i++){
if (list.get(i).equals("hello")){
list.remove(i);
i--;
}
}
//如果想把StringBuffer中的s也删除掉可以参考以下方法
/*for(int i = 0;i<list.size();i++){
//判断该元素是否为StringBuffer类型
if (list.get(i)instanceof StringBuffer){
//转换成String类型再比较
if (list.get(i).toString().equals("hello")){
list.remove(i);
i--;//注意删除元素后需要i--,自己模拟一下很容易想明白的
}
}
//这里list.get(i)得到相应对象与"hello"比较,此时"hello"为String类型
// 所以StringBuffer的对象equals会失败
if (list.get(i).equals("hello")){
list.remove(i);
i--;
}
}*/
//将元素123替换为1000,通过遍历得到123元素的下标并调用集合中的set方法
for(int i = 0 ;i< list.size();i++){
if(list.get(i).equals(123)){
list.set(i,1000);
}
}
}
实验二:
2、使用ArrayList集合,向集合中添加10个整数,并使用Iterator遍历该集合,并查找键盘输入的元素。提示:
• 使用add()方法将元素添加到ArrayList集合中。
• 调用集合的iterator()方法获得Iterator对象,并调用Iterator的hasNext()和next()方法,迭代出集合中的所有元素,完成查找功能,并将重复的元素删除。
思路解析:
- 本题考查Iterator迭代遍历集合
- 似曾相识的查找功能,这次没有像上一题用一个集合存放下标,而是直接输出,这种做法是不如用一个集合存放下标的,赶快自己修改一下吧
- 删除重复元素,大家应该能很自然的想到双重for循环,再用remove删除,但本题指明要用Iterator,那就只能Iterator下面再套一个for循环了,需要注意的是在Iterator中删除元素必须用iterator.remove(),不然会出现严重的空指针错误,如果你还不清楚为什么快去查一查吧o( ̄▽ ̄)ブ
源代码:
public static void main(String[] args) {
ArrayList<Integer> List = new ArrayList<>();
//使用ArrayList集合,向集合中添加10个整数,
for(int i = 0;i<5;i++){
List.add(i);
List.add(i);
}
System.out.println(List);//list:[0, 0, 1, 1, 2, 2, 3, 3, 4, 4]
//查找功能
Scanner sc=new Scanner(System.in);
System.out.println("请输入要查找的数据:");
int n =sc.nextInt();
for (int i = 0; i < List.size(); i++) {
if(n==List.get(i)){
System.out.println(n+"的位置在:"+i);
}
}
//将重复的元素删除
Iterator<Integer> iterator = List.iterator();
while (iterator.hasNext()){
int num = iterator.next();//得到当前元素
int count = 0;//计数
//遍历集合,找到相同元素增加计数
for(int i = 0;i< List.size();i++){
if(List.get(i)==num){
count++;
}
}
//利用iterator的remove()把当前元素删除
if(count>1){
iterator.remove();
}
}
System.out.println("去除重复元素后: "+List);
实验三:
3、分别利用Arraylist和Set随机生成十个不重复的随机整数,随机整数范围为350到450。
思路分析:
- 这道题主要考察用Random类生成随机数
- 需要注意Arraylist可以添加重复元素,所以在添加到时候需要判断是否已经含有此元素,可以用到contains方法
- Set集合不能添加重复元素,内部已经完成去重,不用判断随便放就好
源代码:
public static void main(String[] args) {
/*分别利用Arraylist和Set随机生成十个不重复的随机整数,随机整数范围为350到450。*/
Random random = new Random();
ArrayList<Integer> list = new ArrayList<>();
while (list.size()<10){
int num = random.nextInt(350,450);
//判断当前list中是否已经包含生成的随机数
if(!list.contains(num)){
list.add(num);
}
}
System.out.println("Arraylist的十个随机数:"+list);
Set<Integer> set = new HashSet<>();
while (set.size()<10){
int num = random.nextInt(350,450);
//因为Set本事内部已经去重,无法添加相同的元素所以这里不需要再判断
set.add(num);
}
System.out.println("Set的十个随机数: "+set);
}
实验四:
4、集合中不容许有重复的对象,对于多个重复对象只能添加一次。例如在HashSet集合中添加三个Person对象,把姓名相同的人当做同一个人,虽然可以添加多次但集合里只保留一个,但是这对类的设计是有要求的,假设Person类中只包含name和age属性,则需要重写hashCode()方法和equals()方法,如果两个对象的name相同,则hashCode()方法的返回值相同,equals()方法返回true。
思路解析:
- 这道题考察Set集合存放自定义类需要重写hashCode()方法和equals()方法,关于Set的存放问题涉及其内部源码这里简单解释一下
Set集合在存储元素的过程中首先会去调用元素的hashCode()值,就是根据这个元素得到的一个值注意相同元素的hashCode()值一定相同,但hashCode()值相同元素不一定相同,
然后看存放的元素的哈希值与已经存入Set的元素的哈希值是否相同。
如果都不同 :说明这是一个与已经存放的元素都不相同的元素,就直接添加到集合;
如果相同 :则继续调用元素的equals() 和哈希值相同的这些元素依次去比较。如果说有返回true的,那就说明元素重复,不添加;如果说比较结果都说false,那就是不重复,添加进去。
- 本题要求把姓名相同的人当做同一个人,所以在hashCode()方法中要返回name的hashCode,在比较过程中也是你叫name是否相同
源代码:
public class S6_4 {
public static void main(String[] args) {
HashSet hs=new HashSet();
Person p1=new Person("张三",18);
Person p4=new Person("李四",20);
Person p2=new Person("王五",19);
Person p3=new Person("张三",18);
hs.add(p1);
hs.add(p2);
hs.add(p3);
hs.add(p4);
System.out.println(hs);
}
}
class Person{
String name;
int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
@Override
public int hashCode() {
//返回name的hashcode
return name.hashCode();
}
@Override
public boolean equals(Object obj) {
//首先直接判断传入的obj与this当前对象是否相等
//相等则直接return true
if(this==obj){
return true;
}
//判断传入的obj是否为Person类,不同则肯定不相等false
if(!(obj instanceof Person)){
return false;
}
//将传入的obj转为Person类,再判断名字是否相等
Person p=(Person) obj;
return this.name.equals(p.name);
}
实验五:
5、编写程序将一组学生对象的姓名和成绩存入到一个树集(TreeSet)中,完成以下要求:
• 使得按照成绩自动降序排列,并输出排序的结果。
思路解析
- 本题考察TreeSet的排序问题,分为自然排序与定制排序,我这里用的是自然排序,就是在自定义类中实现Comparable接口并重写compareTo方法
源代码:
public class S6_5 {
public static void main(String[] args) {
Student stu1 = new Student("张三", 88);
Student stu2 = new Student("李四", 99);
Student stu3 = new Student("王五", 77);
TreeSet tset = new TreeSet();
tset.add(stu1);
tset.add(stu2);
tset.add(stu3);
System.out.println(tset);
}
}
class Student implements Comparable <Student>{
String name;
int score;
public Student(String name, int score) {
this.name = name;
this.score = score;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", score=" + score +
'}';
}
@Override
public int hashCode() {
return super.hashCode();
}
@Override
public boolean equals(Object obj) {
return super.equals(obj);
}
@Override
public int compareTo(Student student) {
//加负号为降序,不加为升序
return -Integer.compare(this.score, student.score);
}
}
实验六:
6、编写一个程序,读取个数不定的整数,然后查找其中出现频率最高的数字。要求通过键盘输入数据,当输入为0时,表示结束输入。如: 如果输入的数据是2 3 40 3 54 -3 3 3 2 0,那么数字3的出现频率是最高的。如果出现频率最高的数字不是一个而是多个,则应该将它们全部输出。例如当数据是9 30 3 9 3 2 4时,3和9都出现了两次,3和9都应该输出。
提示:可以利用集合的元素不能重复这一特性。
思路解析:
- 首先我们会想到Map来存储key==value键值对,key为数组,value为该数字出现的次数
- 然后我们再找到value的最大值输出相应的key就好了
源代码:
public class S6_6 {
public static void main(String[] args)
{
Scanner reader=new Scanner(System.in);
//hashMap用来存放数字以及它对应的频率
HashMap<Integer,Integer> hashMap=new HashMap<Integer,Integer>();
System.out.println("请输入数据");
while (true)
{
int num = reader.nextInt();
if (num == 0)
{
break;
}
//如果当前集合中没有该元素,则hashMap.put(num,1);
if(!(hashMap.containsKey(num)))
{
hashMap.put(num,1);
}else {
//如果已经存在该元素,将其value加一
int value = hashMap.get(num);
value+=1;
hashMap.put(num,value);
}
}
int max = 0;
int count = 0;
//得到频率最高为多少即max
Collection<Integer> values = hashMap.values();
for(int num : values){
//先将第一个value赋给max
if(count==0){
max = num;
count++;
}
if(num>max){
max = num;
}
}
System.out.println("当当当当~频率最高的数字如下:");
//得到hashMap对应key的集合
Set<Integer> key = hashMap.keySet();
//遍历key的值再比较其对应的value值,如果value=key,输出key
for(int num : key){
if(hashMap.get(num)==max){
System.out.println(num);
}
}
}
}
实验七:
7、选择合适的Map集合保存5个用户的用户名和密码,然后将这些键值对打印出来。
思路解析:
- 本题简单的考察了Map集合的遍历输出,了解Map的entrySet()方法这道题迎刃而解
源代码:
public class S6_7 {
public static void main(String[] args) {
HashMap hashMap = new HashMap();
hashMap.put("001","123");
hashMap.put("002","234");
hashMap.put("003","345");
hashMap.put("004","456");
hashMap.put("005","567");
Set entrySet = hashMap.entrySet();
Iterator iterator = entrySet.iterator();
while (iterator.hasNext()){
System.out.println(iterator.next());
}
}
}
实验八:
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.,;:!?()]")方法进行分词。
思路分析:
- 同样我们首先想到Map存放单词以及对应出现的次数
- 根据提示,我们可以用String.split(("[ \n\t\r.,;:!?()]")方法将字符串分为字符串数组
源代码:
public class S6_8 {
public static void main(String[] args) {
String str = new String("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!");
//首先将一大串句子中的每个单词通过split转化为string数组
String split[] = str.split(("[ \n\t\r.,;:!?()]"));
//hashmap用来存key==value键值对,其中key为字母,value为该字母出现次数
HashMap hashMap = new HashMap();
for(int i = 0;i<split.length;i++){
if(!(hashMap.containsKey(split[i]))){
hashMap.put(split[i],1);
}else {
int value = (int)hashMap.get(split[i]);
value++;
hashMap.put(split[i],value);
}
}
//普普通通的遍历结束
Set entrySet = hashMap.entrySet();
Iterator iterator = entrySet.iterator();
while (iterator.hasNext()){
System.out.println(iterator.next());
}
}
}
实验九:
9、(选做)500个人围成一个圈,从1开始报数,数到3的倍数的人离开圈子,循环往复,直到最后圈子只剩下一人为止,求剩下的人原来在圈子的位置。
提示:可以使用集合(ArrayList)或队列(Deque)实现。
解题思路:
- 这道题是非常经典的约瑟夫环问题,大家可以先看看我的代码,如果没搞明白强烈建议百度搜一搜,很多人都把这问题解释的十分明白了,是一道经典的算法题。
源代码:
- 集合实现
public class S6_9 {
public static void main(String[] args) {
ArrayList arrayList = new ArrayList();
//添加五百个人
for(int i = 1;i<=500;i++){
arrayList.add(i);
}
int i = 0;//集合的下标
int count = 0;//报数
while (arrayList.size()>1){
count++;//报数加一
if(count==3){
arrayList.remove(i);
i--;//如果这个人离开了,注意i--
count=0;//报数归零
}
//如果到最后一个人了,i归零继续循环
if(i==arrayList.size()-1){
i = 0;
}else {
i++;
}
}
System.out.println("最后一个人为:"+arrayList);
}
}
- 队列实现
public class S6_9 {
public static void main(String[] args) {
Queue<Integer> loop = new LinkedList<Integer>() ;//保存元素用于计算
//n个元素入队loop
for(int i=1;i<=500;i++) {
loop.offer(i);
}
int count = 0;//计数,逢3出队
int num = 0;
while (loop.size()>1){
//先出队,得到当前出队的元素,
//如果count=3,不再入队,否则入队到队尾,实现循环
num = loop.poll();
count++;
if(count==3) {
count=0;
}
else {
loop.offer(num);
}
}
//loop最后只剩一个元素
System.out.println(loop);
}
}
🎉文章到这里就结束了,感谢诸佬的阅读。🎉💕欢迎诸佬对文章加以指正,也望诸佬不吝点赞、评论、收藏加关注呀😘