C++转Java日记(05)

ArrayList(续)

删除

删除的是下标,还是元素值?答案是都有可能。

我们来看ArrayList的两个重载版本。

remove(int index) //按下表删除,并返回被删除的元素。

remove(Object o) //暗元素只删除第一个匹配项,并返回是否删除成功(有返回值)。

比如remove(1)表示删除索引为1的位置,并且让后面元素的往前挪。

那么,如果我要删除数字1本身(也就是这个ArrayList里含1的第一个位置)怎么办呢?就需要明确传入一个Integer对象nums.remove(Integer.valueOf(1))

java 复制代码
import java.util.ArrayList;

public class Main {
    public static void main(String[] args) {
        ArrayList<Integer> numbers=new ArrayList<>();
        numbers.add(10);
        numbers.add(20);
        numbers.add(30);
        numbers.add(20);
        boolean removed=numbers.remove(Integer.valueOf(20));
        System.out.println("Element removed: " + removed);
        System.out.println("Updated ArrayList: " + numbers);
    }
}

而对于字符串列表等就可以直接写names.remove("奶龙")。

说到这里我们还需要注意一个点,循环删除内容时需要小心元素向前移动的问题。

java 复制代码
import java.util.ArrayList;

public class Main {
    public static void main(String[] args) {
        ArrayList<Integer> numbers=new ArrayList<>();
        numbers.add(10);
        numbers.add(20);
        numbers.add(30);
        for(int i=0;i<numbers.size();i++){
            if(numbers.get(i)<25){
                numbers.remove(i);
            }
        }
    }
}

这样写只会删掉10,不会删掉20,因为执行remove后20的下标变成0,而原先的i已经过掉0了。

所以合适的解决方法有两个:在后面写i--,或者从i=numbers.size()-1开始i--倒序遍历到0。

综合运用

java 复制代码
import java.util.ArrayList;

public class Main {
    public static void main(String[] args) {
        ArrayList<Student> students = new ArrayList<>();
        Student a=new Student("小明", 90);
        students.add(a);
        students.add(new Student("小红", 85));
        for(Student s:students){
            s.showInfo();
            if(s.getName().equals("小红")){
                s.setScore(95);
            }
        }
    }
}
class Student {
    private String name;
    private int score;
    Student(String name, int score) {
        this.name = name;
        this.score = score;
    }
    public String getName() {
        return name;
    }
    public int getScore() {
        return score;
    }
    public int setScore(int score) {
        this.score = score;
        return score;
    }
    public void showInfo() {
        System.out.println("姓名:" + name + ",成绩:" + score);
    }
}

HashMap

通过键查找值的集合,用途接近C++中的unordered_map。(ArrayList是根据键取值)。

创建添加查询

java 复制代码
import java.util.HashMap;

public class Main {
    public static void main(String[] args) {
        HashMap<String, Integer> scores = new HashMap<>();
        scores.put("小明", 90);
        scores.put("小红", 85);
        System.out.println("小明的成绩: " + scores.get("小明"));
        System.out.println("小红的成绩: " + scores.get("小红"));
    }
}

这里有两个泛型参数,键的类型和值的类型都是泛型的。读取用get(),添加或修改用put()。

键不能重复,重复put会替换值。比如:

scores.put("小明", 100);

scores.put("小明", 90);

System.out.println(scores.get("小明")); //90

System.out.println(scores.size()); //1

键不存在时,get()返回null,null表示没有任何引用对象。

System.out.println(scores.get("小李"));

null表示没有引用任何对象,这里返回的类型是Integer,所以能够返回null。但是如果:

int score=scores.get("小李");

这在运行时会抛出NullPointerException:Java想把Integet自动拆箱成int,但是拿到的却是null。

int score=scores.getOrDefault("小李",0);

System.out.println(score); //0

这样就对了。getOrDefault只会返回默认值,不会把键添加进Map。

常用操作

scores.containsKey("小明"); // 判断是否存在这个键

scores.remove("小明"); // 删除这个键及对应的值

scores.size(); // 键值对数量

scores.isEmpty(); // 是否为空

java 复制代码
for (String name : scores.keySet()) {
    System.out.println(name + ": " + scores.get(name));
}

其中keySet()返回所有键组成的集合(也就是键这一列)。

HashMap不保证遍历顺序,不能依赖它按照添加顺序输出。

实例

再次注意:键不能重复,重复则put会替换值。

练习之计数问题:

java 复制代码
import java.util.HashMap;

public class Main {
    public static void main(String[] args) {
        int[] nums = {2,3,2,5,3,2};
        HashMap<Integer, Integer> map = new HashMap<>();
        for(int num:nums){
            map.put(num,map.getOrDefault(num, 0)+1);
        }
        System.out.println(map);
    }
}

练习之常见函数

java 复制代码
import java.util.HashMap;

public class Main {
    public static void main(String[] args) {
        HashMap<String, Integer> map =new HashMap<>();
        map.put("A",10);
        map.put("B",20);
        map.put("A",30);
        int x=map.getOrDefault("C",0);
        System.out.println(map.get("A"));
        System.out.println(x);
        System.out.println(map.size());
    }
}

答案是30 0 2,这里最重要的就是put会覆盖原来的值,以及getOrDefault不会把键添加给Map。

HashSet

保存不重复元素的集合,用途接近C++的unordered_set。

创建添加删除查找

java 复制代码
import java.util.HashSet;

public class Main {
    public static void main(String[] args) {
        HashSet<Integer> nums = new HashSet<>();

        System.out.println(nums.add(10)); // true:添加成功
        System.out.println(nums.add(20)); // true
        System.out.println(nums.add(10)); // false:已经存在,不重复添加

        System.out.println(nums.size());       // 2
        System.out.println(nums.contains(10)); // true

        nums.remove(10);

        System.out.println(nums.contains(10)); // false
    }
}

注意方法名的区别:

map.containsKey(key); // HashMap:判断键是否存在

set.contains(value); // HashSet:判断元素是否存在

下标问题

HashSet没有下标,也不保证遍历顺序。

因此HashSet的remove(10)是删除数值10,不会像ArrayList那样当成下标,因为没有按下标删除的重载。

也可以用for(int num:nums)来遍历,但不能依赖输出顺序与添加顺序相同。

去重问题

HashSet<String> name=new HashSet<>();

name.add(new String("小明"));

name add(new String("小明"));

System.out.println(names.size()); //1

虽然创建了两个不同的字符串对象,但是HashSet判断重复会结合元素的hashCode()和equals()。

实例

判断是否重复

java 复制代码
    public static boolean hasDuplicate(int[] nums) {
        HashSet<Integer> set=new HashSet<>();
        for(int num:nums) {
            if(set.contains(num)){
                return true;
            }
            set.add(num);
        }
        return false;
    }

中间的if也可以写成if(!set.add(num)),因为添加会返回值,如果添加失败给出0,说明这个数字之前出现过。

练习

java 复制代码
import java.util.HashSet;

public class Main {
    public static void main(String[] args) {
        HashSet<Integer> set = new HashSet<>();
        set.add(1);
        set.add(2);
        set.add(1);
        boolean a=set.remove(1);
        boolean b=set.remove(1);
        System.out.println(a); // true
        System.out.println(b); // false
        System.out.println(set.size()); // 1
    }
}
相关推荐
CoderYanger6 小时前
Java EE 进阶:8.MyBatis 操作数据库(入门)(第二弹)
java·数据库·spring boot·spring·面试·java-ee·mybatis
CQU_JIAKE8 小时前
11.7[高体】
java·后端·spring
apcipot_rain9 小时前
C++转Java日记(04)
java·开发语言·c++
特立独行的猫A9 小时前
我给女儿写了个打字练习:一边敲键盘,一边把小学英语单词记牢
java·后端·python
云和数据.ChenGuang10 小时前
LangGraph 异步 Node 的设计与写法实践
开发语言·人工智能·python·机器学习·php
憧憬成为java架构高手的小白11 小时前
LangGraph4j 实战(下)
java
WL学习笔记11 小时前
vector模拟实现
c++
天诰11 小时前
SA-K-11 检索会消失吗与四个未解问题
java·服务器·人工智能·python·机器学习·ai编程
蜗牛一步步往上爬14 小时前
第十六章 C++语言在深度学习中的应用
开发语言·c++·深度学习