• Comparable比较器写法&ClassCastExcption类转换异常


    集合类图,如下所示

     

    list集合

    遍历方式:下标,forEach,迭代器(小编推荐使用)

    初始化

    1. List<Integer> list = new ArrayList<>();
    2. //初始化
    3. @Before
    4. public void setup() {
    5. list.add(1);
    6. list.add(3);
    7.        list.add(3);
    8. list.add(4);
    9. list.add(2);
    10. }

    结果:[1,3,3,4,2]

    1. @Test
    2. //迭代器遍历
    3. public void test03() {
    4. Iterator<Integer> iterator = list.iterator();
    5. while (iterator.hasNext()) {
    6. System.out.println(iterator.next());
    7. }
    8. }

    list集合怎么删除元素??

    1. @Test
    2. //最好用迭代器删除,不易出错
    3. public void test04() {
    4. Iterator<Integer> iterator = list.iterator();
    5. while (iterator.hasNext()) {
    6. if(iterator.next()==3) {
    7. iterator.remove();
    8. }
    9. }
    10. System.out.println(list);
    11. }

    注意事项:

    结果:[1,3, 2]

    1. @Test
    2. public void test05() {
    3. list.remove(3);
    4. list.remove(Integer.valueOf(3));
    5. System.out.println(list);
    6. }

    list.remove(3);删除的是指定下标;

    list.remove(Integer.valueOf(3));删除的一个指定的对象;

    实现目标:[1,4,2]

    结果:[1,3,4,2]

    1. @Test
    2. public void test01() {
    3. for (int i = 0; i < list.size(); i++) {
    4. if(list.get(i)==3) {
    5. list.remove(i);
    6. }
    7. }
    8. System.out.println(list);
    9. }

    解决方案

    1. @Test
    2. public void test01() {
    3. for (int i = 0; i < list.size(); i++) {
    4. if(list.get(i)==3) {
    5. list.remove(i--);
    6. }
    7. }
    8. System.out.println(list);
    9. }

    小编经验:当找到为第一个3(下标1)的下标时,删除之后,第一个3就为空了;第二个3(下标2)往前挤了一个下标,变成了(下标1)

    Arraylist的一些特性:

    • 简单数据结构,超出容量自动扩容,动态数组

    • 内部实现是基于基础的对象数组的

    • 随机访问快

    • 不适合随机增加或删除

    • 线程不安全

    LinkedList的一些特性:

    • LinkedList可被用作堆栈(stack)【包括了push,pop方法】,队列(queue)或双向队(deque)

    • Vector:线程安全(单独使用线程,等它使用完别人才能使用),性能慢。

    CopyOnWriteArrayList的一些特性:

    写的时候复制,完成所有操作后,将已经操作完成的数据直接给array,保持了最终一致性。

    Set集合

    遍历方式:forEach,迭代器

    特点:无序,不重复

    HashSet集合

    它存储唯一元素并允许空值,不保持插入顺序

    下面是去重例子

    结果:[1,2,3]

    初始化

    1. private List<Integer> list = new ArrayList<>();
    2. private Set<Integer> set=new HashSet<Integer>();
    3. @Before
    4. public void satrt() {
    5. list.add(1);
    6. list.add(2);
    7. list.add(1);
    8. list.add(2);
    9. list.add(3);
    10. list.add(3);
    11. set.add(1);
    12. set.add(1);
    13. set.add(2);
    14. set.add(3);
    15. set.add(3);
    16. set.add(2);
    17. }
    1. @Test
    2. public void test01() {
    3. List<Integer> sa=new ArrayList<>(new HashSet<Integer>(list));
    4. System.out.println(sa);//给list去重
    5. }
    6. @Test
    7. public void test02() {
    8. for(Integer e: set) {
    9. System.out.println(e);
    10. }
    11. }

    TreeSet集合

    1. 是一个包含有序的且没有重复元素的集合,作用是提供有序的Set集合

    2. 自然排序或者根据提供的Comparator进行排序

    3. TreeSet集合与HashSet的区别,插入结果是否进行排序。

    error错误类型转换异常:

    ClassCastExcption类转换异常,stu.add(new Student(1, "zs", 12))添加不进去。

    解决方法:实现Comparable(比较器),然后重写比较器的方法即可。

    按年龄排序结果如下

    1. Student [sid=7, sname=lihao, age=1]
    2. Student [sid=4, sname=lihao, age=10]
    3. Student [sid=1, sname=zs, age=12]
    4. Student [sid=2, sname=ls, age=19]
    5. Student [sid=5, sname=zengfanyan, age=20]
    6. Student [sid=3, sname=we, age=30]

    Test

    1. @Test
    2. public void test04() {
    3. Set<Student> stu = new TreeSet<Student>();
    4. stu.add(new Student(1, "zs", 12));
    5. stu.add(new Student(2,"ls", 19));
    6. stu.add(new Student(4,"lihao", 10));
    7. stu.add(new Student(7,"lihao", 1));
    8. stu.add(new Student(5,"zengfanyan", 20));
    9. stu.add(new Student(3,"we", 30));
    10. for(Student s: stu) {
    11. System.out.println(s);
    12. }
    13. }

    Student实体必须实现Comparable(比较器)

    比较者大于被比较者 返回1

    比较者等于被比较者 返回0

    比较者小于被比较者 返回-1

    写法一
    
    1. public class Student implements Comparable<Student>{
    2. @Override
    3. public int compareTo(Student o) {
    4. if(this.getAge()-o.getAge()==0) {
    5. return this.getSid()-o.getSid();
    6. }
    7. return this.getAge()-o.getAge();
    8. }
    写法二
    
    1. public class Student implements Comparable<Student>{
    2. @Override
    3. public int compareTo(Student o) {
    4. if(this.getSid()>o.getSid()) {
    5. return 1;
    6. }else{
    7.           if(this.getSid()==o.getSid()) {
    8. return 0;
    9.       }else{
    10.        if(this.getSid()<o.getSid()){
    11.            return -1;
    12.     }
    13. }
    14. }

    上面代码与这个代码一样的

    写法三
    
    return this.getAge()-o.getAge();

    Map集合

    特点:无序,键值对现实存在,键不能重复,值可以重复

    如果键重复则覆盖,没有继承Collection接口

    遍历方式

    初始化

    1. Map<String, String> map=new TreeMap<>();
    2. @Before
    3. public void satrtUp() {
    4. map.put("1", "lkf");
    5. map.put("2", "zs");
    6. map.put("3", "ls");
    7. map.put("4", "wu");
    8. map.put("5", "ll");
    9. }

    通过keySet遍历

    先获取所有键的Set集合,再遍历(通过键获取值)

    结果:[lkf,zs,ls,wu,ll]

    1. /**
    2. * 获取HashMap集合上的键的集合,保存ketSet集合里,然后使用ketSet集合自己的迭代器遍历
    3. */
    4. @Test
    5. public void test01() {
    6. Iterator<String> iterator = map.keySet().iterator();
    7. while (iterator.hasNext()) {
    8. String Key = iterator.next();
    9. System.out.println(map.get(Key));
    10. }
    11. }

    通过entrySet遍历

    取出保存所有Entry的Set,再遍历此Set即可

    结果:[1:kk,2:yy,3:zz]

    1. @Test
    2. public void test02() {
    3. Map<String, String> maps=new HashMap<>();
    4. maps.put("1", "kk");
    5. maps.put("2", "yy");
    6. maps.put("3", "zz");
    7. Iterator<Entry<String, String>> iterator = maps.entrySet().iterator();//通过enrty获取自身的迭代器
    8. while (iterator.hasNext()) {//hasNext()判断该迭代器有无元素
    9. Entry<String, String> next = iterator.next();//entrySet()可获取键和值,属于一个集合
    10. System.out.println(next.getKey()+":"+next.getValue());
    11. }
    12. }

    如何对已存在的key为1的记录进行了覆盖???

    原结果:[1:lkf,2:zs,3:ls,4:wu,5:ll]

    现结果:[1:yyy,2:zs,3:ls,4:wu,5:ll]

    1. @Test
    2. public void test06() {
    3. //对已存在的key为1的记录进行了覆盖
    4. map.put("1", "yyy");
    5. Iterator<Entry<String, String>> iterator = map.entrySet().iterator();
    6. while (iterator.hasNext()) {//hasNext()判断该迭代器有无元素
    7. Entry<String, String> next = iterator.next();//entrySet()可获取键和值,一个集合
    8. System.out.println(next.getKey()+":"+next.getValue());
    9. }
    10. }

    HashMap集合

    特点:线程不安全,最常用,速度快

    基本原理:内部采用数组来存放数据

    红黑树结果示图

     

    红黑树怎么查找数据的?

    通过数组下标,先找到指定下标的元素比较大小;如果比上一个元素下标大,就继续往下找,该链条上下一个元素下标;直到找到比该元素小的下标为止。

    链条查找元素一般的找靠right(右边)的元素

    TreeMap集合

    key值按一定的顺序排序,但是比HashMap慢;因为需求维护内部的红黑树,用于保证key值的顺序

    1. Map<String, Student> tree=new TreeMap<String, Student>();
    2. @Before
    3. public void satrtUp() {
    4. tree.put("1", new Student(1, "zs",11));
    5. tree.put("2", new Student(2,"sb",12));
    6. tree.put("3", new Student(3,"ljj",13));
    7. tree.put("4", new Student(4,"zyz",14));
    8. tree.put("5", new Student(5,"yyxq",15));
    9. }

    结果如下:

    1. 1:Student [sid=1, sname=zs, age=11]
    2. 2:Student [sid=2, sname=sb, age=12]
    3. 3:Student [sid=3, sname=ljj, age=13]
    4. 4:Student [sid=4, sname=zyz, age=14]
    5. 5:Student [sid=5, sname=yyxq, age=15]
    1. @Test
    2. public void demo01() {
    3. tree.forEach((key, val) -> System.out.println(key + ":" + val));
    4. }

    linkedHashMap集合

    LinkedHashMap是有序的,且默认为插入顺序;

    使用环境:当我们希望有顺序地去存储key-value时,就需要使用LinkedHashMap了

    结果如下

    1. 1:Student [sid=1, sname=zs, age=11]
    2. 2:Student [sid=2, sname=sb, age=12]
    3. 3:Student [sid=3, sname=ljj, age=13]
    4. 4:Student [sid=4, sname=zyz, age=14]
    5. 5:Student [sid=5, sname=yyxq, age=15]
    1. /**
    2. * linkedHashMap遍历
    3. */
    4. @Test
    5. public void demo02() {
    6. Map<String, String> link=new LinkedHashMap<>();
    7. Set<Entry<String,String>> entrySet = link.entrySet();//获取entrySet集合
    8. Iterator<Entry<String, String>> iterator = entrySet.iterator();//通过enrty获取自身的迭代器
    9. while (iterator.hasNext()) {
    10. Entry<String, String> next = iterator.next();//entrySet()可获取键和值,属于一个集合
    11. System.out.println(next.getKey()+":"+next.getValue());
    12. }
    13. }

  • 相关阅读:
    技术速递|宣布为 .NET 升级助手提供第三方 API 和包映射支持
    C语言宏的几种常用语法与示例
    力扣第572题 另一棵树的子树 c++深度(DFS)注释版
    算法+数据结构=程序,程序员怎样才能学好算法?
    Rust trait、动态派发和向上转型
    服务器怎么买,腾讯云服务器购买三种流程介绍
    链表及其基本操作
    软考-软件开发模型
    Shiro 登录认证源码详解
    StrictMode分析Activity泄漏-StrictMode原理(3)
  • 原文地址:https://blog.csdn.net/Bugxiu_fu/article/details/125527285