菜鸟之路Day08一一集合进阶(一)

简介: 《菜鸟之路Day08——集合进阶(一)》由blue撰写于2025年1月26日,深入探讨了五道经典算法题及单列集合的相关知识。文章首先通过自定义排序、不死神兔、猴子吃桃子、爬楼梯及其变种等题目,详细讲解了Java中数组和动态规划的应用;接着介绍了单列集合的体系结构,重点解析了Collection接口的常用方法及遍历方式(迭代器、增强for、Lambda表达式),并进一步探讨了List接口的特点与遍历方法,最后简要介绍了LinkedList的独特API。

菜鸟之路Day08一一集合进阶(一)

作者:blue

时间:2025.1.26

1.五道经典算法题

为什么要做算法题,个人理解一个是锻炼解决问题的思维,另一个是熟悉如何用这个语言来解决具体的问题,所以练习算法题是非常有必要的,断然不可跳过这个阶段。

1.1自定义排序

定义数组存储一些女朋友对象,利用Arrays中的sort方法

要求1:属性有姓名,年龄,身高

要求2:按照年龄大小进行排序,年龄一样,按照身高排序,身高一样按照姓名的字母进行排序

解题:

①先创造女朋友类,注意在这个Javabean类中,我重写了toString方法,为了一会打印出来方便查看

package Test;

public class Girl {
   
    private String name;
    private int age;
    private double high;

    public Girl() {
   
    }

    public Girl(String name, int age, double high) {
   
        this.name = name;
        this.age = age;
        this.high = high;
    }

    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;
    }

    public double getHigh() {
   
        return high;
    }

    public void setHigh(double high) {
   
        this.high = high;
    }

    @Override
    public String toString() {
   
        return "Girl{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", high=" + high +
                '}';
    }
}

②创建对象,加入数组,进行自定义排序

package Test;

import java.util.Arrays;
import java.util.Comparator;

public class Test1 {
   
    public static void main(String[] args) {
   
        Girl g1 = new Girl("xm",20,173);
        Girl g2 = new Girl("xw",20,173);
        Girl g3 = new Girl("xn",20,173);

        Girl[] arr = {
   g1,g2,g3};
        System.out.println(Arrays.toString(arr));
        //匿名内部类
        /*Arrays.sort(arr, new Comparator<Girl>() {
            @Override
            public int compare(Girl o1, Girl o2) {
                int temp1;
                double temp2;
                int temp3;
                temp1 = o1.getAge()- o2.getAge();
                temp2 = o1.getHigh() - o2.getHigh();
                temp3 = o1.getName().compareTo(o2.getName());
                if(temp1==0&&temp2==0) return temp3;
                if(temp1==0){
                    if(temp2>0) return 1;
                    else if(temp2<0) return -1;
                }
                return temp1;
            }
        });*/

        //Lambda表达式
        Arrays.sort(arr, (Girl o1, Girl o2)->{
   
            int temp1;
            double temp2;
            int temp3;
            temp1 = o1.getAge()- o2.getAge();
            temp2 = o1.getHigh() - o2.getHigh();
            temp3 = o1.getName().compareTo(o2.getName());
            if(temp1==0&&temp2==0) return temp3;     //针对返回值的解释:
            if(temp1==0){
                              //负数:表示当前插入的元素是小的,放在前面
                if(temp2>0) return 1;                //正数:表示当前插入的元素是大的,放在后面
                else if(temp2<0) return -1;             //0:表示当前插入的元素是一样大的,也放在后面
            } 
            return temp1;
        });
        System.out.println(Arrays.toString(arr));
    }
}

1.2不死神兔

有一个很有名的数学逻辑题叫做不死神兔问题,有一对兔子,从出生后第三个月起每个月都生一对兔子,小兔子长到第三个月后每个月又生一对兔子,假如兔子不死,问第12个月的兔子对数为多少

解题:没什么特别的,画完图之后发现是fibonacci数列,dp切了

image-20250126121306503.png

public class Test2 {
   
    public static void main(String[] args) {
   
        int[] dp = new int[13];
        dp[0]=0;
        dp[1]=1;
        for(int i=2;i<=12;i++) dp[i]=dp[i-1]+dp[i-2];
        System.out.println("第12个月的兔子数量为:"+dp[12]);
    }
}

1.3猴子吃桃子

有一堆桃子,猴子第一天吃了其中的一半,并多吃了一个!以后每天猴子都吃了当前剩下来的一半,然后再多吃一个,第10天的时候(还没吃),发现只剩下一个桃子了,请问,最初有多少个桃子。

dp切了

public class Test3 {
   
    public static void main(String[] args) {
   
        int[] dp = new int[10];//dp[i],表示第i天剩下dp[i]个桃子
        dp[9]=1;//第十天没吃,剩1个,说明第9天剩1个
        for(int i=8;i>=0;i--) dp[i]=(dp[i+1]+1)*2;
        System.out.println("最初的桃子数为:"+dp[0]);
    }
}

1.4爬楼梯

可爱的小明非常喜欢爬楼梯,他一次可以爬1个或2个台阶,如果这个楼梯有20个台阶,请问小明一共有多少种爬法

解题:dp经典题目,搞清楚dp数组的含义便不难理解

public class Test4 {
   
    public static void main(String[] args) {
   
        int[] dp = new int[21];
        dp[1]=1;
        dp[2]=2;//可以从第0阶两步上来,可以从第1阶一步上来
        for(int i=3;i<=20;i++) dp[i]=dp[i-1]+dp[i-2];
        //dp[i]表示爬上第i阶楼梯的方法数为dp[i]
        //dp[i]可以由第i-1阶楼梯爬1级上来,也可以由i-2阶楼梯爬2级上来
        //故而dp[i]=dp[i-1]+dp[i-2]
        System.out.println("登上第20级台阶,有"+dp[20]+"种爬法");
    }
}

1.5爬楼梯plus

现在小明升级了,他一次可以爬1个或2个台阶或3个台阶,那么问如果有20个台阶,有几种爬法

public class Test5 {
   
    public static void main(String[] args) {
   
        int[] dp = new int[21];
        dp[1]=1;
        dp[2]=2;
        dp[3]=4;//(1+1+1),(1+2),(2+1),(3)
        for(int i=4;i<=20;i++) dp[i]=dp[i-1]+dp[i-2]+dp[i-3];
        System.out.println("登上第20级台阶,有"+dp[20]+"种爬法");
    }
}

2.单列集合

2.1单列集合体系结构

image-20250126141622146.png

2.2Collection

2.2.1Collection的常用方法

Collection是所有单列集合的祖宗接口,他的功能所有单列集合都可以继承使用,以下对其6个功能做一个实验

package Collection;

import java.util.ArrayList;
import java.util.Collection;

public class CollectionTest {
   
    public static void main(String[] args) {
   
        //因为Collection是一个接口,所以这里我们只能以多态的方式来创建它的对象
        Collection<String> coll = new ArrayList<>();

        //1.public boolean add(E e)  添加
        coll.add("aaa");//注意其返回值为boolean类型,添加成即为true,失败为false
        coll.add("bbb");//List永远是成功的,而Set由于不能重复,所以有可能会false
        coll.add("ccc");
        System.out.println(coll);

        //2.public void clear() 清空

        //3.public boolean remove(E e) 删除
        coll.remove("aaa");//它是根据对象来删除,因为Set是无索引的,所以这种共性的方法,是不能用索引来删除的
        System.out.println(coll);

        //4.public boolean contain(Object obj)  判断集合是否包含
        //这个方法底层是Object的equals方法实现的,对于引用数据类型他是根据地址值来进行判断的
        //所以如果针对我们自定义类型的集合,想实现用值来查询是否包含,必须在自定义的javabean中重写equals方法
        System.out.println(coll.contains("aaa"));

        //5.public boolean isEmpty() 判断是否为空
        System.out.println(coll.isEmpty());

        //6.public int size() 集合长度
        System.out.println(coll.size());
    }
}

2.2.2Collection系列集合的通用遍历方式

由于Collection系列中的Set系列是无索引的,所以针对Collection系列,我们应该有通用的遍历方式

2.2.2.1迭代器遍历
public class CollectionTest1 {
   
    public static void main(String[] args) {
   
        /*
            迭代器遍历相关的三个方法(注意是三个方法!!!!)
                Iterator<E> iterator(); 获取一个迭代器对象
                boolean hasNext();      判断当前指向的位置是否有元素
                E next();               获取当前指向的元素并移动指针
        */

        Collection<String> coll = new ArrayList<>();
        coll.add("aaa");
        coll.add("bbb");
        coll.add("ccc");
        coll.add("ddd");

        //迭代器遍历
        Iterator<String> it = coll.iterator();
        while(it.hasNext()){
   
            System.out.println(it.next());//获取当前指向的元素并移动指针
        }
        /*注意点:1.迭代器遍历结束,指针不会复位,想再次遍历必须再次获取迭代器对象
                2.循环中只能用1次next方法
                3.迭代器遍历时不能用集合的方法进行增加或删除,这样子会有并发错误
                只能用迭代器自身的remove方法来删除元素
        */ 
    }
}
2.2.2.2增强for遍历

增强for是JDK5以后出现的,底层就是迭代器,注意只有Collection系列的集合才能用增强for

比如刚才的代码,就可以变成

Collection<String> coll = new ArrayList<>();
coll.add("aaa");
coll.add("bbb");
coll.add("ccc");
coll.add("ddd");

//增强for遍历
//s是一个第三方变量,如果你对s做修改,是不会影响集合中的元素的
for (String s : coll) {
   
    System.out.println(s);//获取当前指向的元素并移动指针
}
2.2.2.3Lambda表达式遍历
package Collection;

import java.util.ArrayList;
import java.util.Collection;
import java.util.function.Consumer;

public class CollectionTest2 {
   
    public static void main(String[] args) {
   
        Collection<String> coll = new ArrayList<>();
        coll.add("aaa");
        coll.add("bbb");
        coll.add("ccc");

        /*匿名内部类的方式
        coll.forEach(new Consumer<String>() {
            @Override
            //s依次表示集合中的每一个数据
            public void accept(String s) {
                System.out.println(s);
            }
        });
        */

        //Lambda表达式
        coll.forEach((String s)->{
   
            System.out.println(s);
        });
    }
}

2.3List

List是Collection中的一种,特点是有序,有索引,可重复,Collection中的所有方法List都继承了。

List其实也是一个接口,所以我们依然不能直接创建它的对象,只能创建它实现类的对象。

2.3.1List的特有方法

List是有索引的,所以List中有很多与索引有关的操作,以下实验其针对索引的操作

public class ListTest1 {
   
    public static void main(String[] args) {
   
        List<String> list = new ArrayList<>();
        list.add("aaa");
        list.add("bbb");
        list.add("ccc");

        //1.void add(int index,E element) 在指定位置插入元素
        list.add(1,"AAA");
        System.out.println(list);//原来位置上的元素,会被依次往后退一个

        System.out.println("==================================");

        //2.E remove(int index) 删除指定位置的元素,并且会返回这个被删除的元素
        String x = list.remove(1);
        System.out.println(x);

        System.out.println("==================================");

        //3.E set(int index,E element) 修改指定索引处的元素,返回被修改的元素
        String y = list.set(1,"xxx");
        System.out.println(list);
        System.out.println(y);

        System.out.println("==================================");

        //4.E get(int index) 返回指定索引处的元素
        String s = list.get(1);
        System.out.println(s);
    }
}

2.3.2List的遍历方式

List比起Collection,多两种与索引有关的遍历方式

普通for

public class ListTest2 {
   
    public static void main(String[] args) {
   
        List<String> list = new ArrayList<>();
        list.add("aaa");
        list.add("bbb");
        list.add("ccc");
        for(int i=0;i<list.size();i++){
   
            System.out.println(list.get(i));
        }
    }
}

列表迭代器

public class ListTest2 {
   
    public static void main(String[] args) {
   
        List<String> list = new ArrayList<>();
        list.add("aaa");
        list.add("bbb");
        list.add("ccc");

        //列表迭代器
        //额外添加了一个方法,在遍历的过程中,可以添加元素
        ListIterator<String> it = list.listIterator();
        while(it.hasNext()){
   
            String str = it.next();
            if("bbb".equals(str)){
   
                it.add("qqq");
            }
        }
        System.out.println(list);
    }
}

2.4LinkedList

LinkedList底层的数据结构是双向链表,查询慢,增删快,但是如果操作的是首尾元素,速度也是极快的,所以它多了很多首位操作特有的API(混个眼熟)

基本都可以见名知意

public void addFirst(E e);
public void addLast(E e);
public E getFirst();
public E getLast();
public E removeFirst();
public E removeLast();
目录
相关文章
|
10月前
|
监控 关系型数据库 MySQL
|
10月前
|
前端开发 Java 开发者
【springboot】中使用--WebMvcConfigurer
通过实现 `WebMvcConfigurer` 接口,Spring Boot 开发者可以灵活地自定义和扩展 Spring MVC 的配置。无论是视图解析、拦截器、跨域请求处理,还是静态资源和消息转换器配置,`WebMvcConfigurer` 都提供了一致的接口来实现这些功能。掌握这些配置方法,可以使开发者在 Spring Boot 项目中更加游刃有余地进行各种定制化需求的开发。
498 14
|
10月前
|
JSON 关系型数据库 PostgreSQL
PostgreSQL 9种索引的原理和应用场景
PostgreSQL 支持九种主要索引类型,包括 B-Tree、Hash、GiST、SP-GiST、GIN、BRIN、Bitmap、Partial 和 Unique 索引。每种索引适用于不同场景,如 B-Tree 适合范围查询和排序,Hash 仅用于等值查询,GiST 支持全文搜索和几何数据查询,GIN 适用于多值列和 JSON 数据,BRIN 适合非常大的表,Bitmap 适用于低基数列,Partial 只对部分数据创建索引,Unique 确保列值唯一。
|
10月前
|
机器学习/深度学习 人工智能 算法
《AI芯片:如何让硬件与AI计算需求完美契合》
在人工智能快速发展的今天,AI芯片成为推动该领域前行的关键力量。AI芯片如同“超级大脑”,支撑着从智能语音助手到自动驾驶汽车等各种复杂应用。它通过GPU、ASIC和FPGA等架构,优化矩阵运算、内存管理和数据传输,满足大规模数据处理需求。尽管面临通用性和成本挑战,未来AI芯片有望在异构计算、新兴技术和降低成本方面取得突破,为AI发展注入强大动力。
510 17
|
10月前
|
人工智能 开发者 Python
Chainlit:一个开源的异步Python框架,快速构建生产级对话式 AI 应用
Chainlit 是一个开源的异步 Python 框架,帮助开发者在几分钟内构建可扩展的对话式 AI 或代理应用,支持多种工具和服务集成。
1076 9
|
10月前
|
IDE 测试技术 项目管理
【新手必看】PyCharm2025 免费下载安装配置教程+Python环境搭建、图文并茂全副武装学起来才嗖嗖的快,绝对最详细!
PyCharm是由JetBrains开发的Python集成开发环境(IDE),专为Python开发者设计,支持Web开发、调试、语法高亮、项目管理、代码跳转、智能提示、自动完成、单元测试和版本控制等功能。它有专业版、教育版和社区版三个版本,其中社区版免费且适合个人和小型团队使用,包含基本的Python开发功能。安装PyCharm前需先安装Python解释器,并配置环境变量。通过简单的步骤即可在PyCharm中创建并运行Python项目,如输出“Hello World”。
3724 13
【新手必看】PyCharm2025 免费下载安装配置教程+Python环境搭建、图文并茂全副武装学起来才嗖嗖的快,绝对最详细!
|
8月前
|
存储 网络协议 安全
Java网络编程,多线程,IO流综合小项目一一ChatBoxes
**项目介绍**:本项目实现了一个基于TCP协议的C/S架构控制台聊天室,支持局域网内多客户端同时聊天。用户需注册并登录,用户名唯一,密码格式为字母开头加纯数字。登录后可实时聊天,服务端负责验证用户信息并转发消息。 **项目亮点**: - **C/S架构**:客户端与服务端通过TCP连接通信。 - **多线程**:采用多线程处理多个客户端的并发请求,确保实时交互。 - **IO流**:使用BufferedReader和BufferedWriter进行数据传输,确保高效稳定的通信。 - **线程安全**:通过同步代码块和锁机制保证共享数据的安全性。
348 23
|
10月前
|
机器学习/深度学习 算法 数据可视化
利用SVM(支持向量机)分类算法对鸢尾花数据集进行分类
本文介绍了如何使用支持向量机(SVM)算法对鸢尾花数据集进行分类。作者通过Python的sklearn库加载数据,并利用pandas、matplotlib等工具进行数据分析和可视化。
933 70
|
10月前
|
算法 Java 程序员
菜鸟之路Day06一一Java常用API
《菜鸟之路Day06——Java常用API》由blue编写,发布于2025年1月24日。本文详细介绍了Java中常用的API,包括JDK7的时间类(Date、SimpleDateFormat、Calendar)和JDK8新增的时间API(ZoneId、Instant、DateTimeFormatter等),以及包装类的使用。通过多个实例练习,如时间计算、字符串转整数、十进制转二进制等,帮助读者巩固所学内容,提升编程技能。文章强调了理论与实践结合的重要性,鼓励读者多做练习以提高学习效率。
195 28
|
9月前
|
SQL 数据安全/隐私保护 索引
SQL语句速成
《SQL语句速成》由blue编写,涵盖建表、插入、查询、更新、删除、视图创建、权限管理及索引操作等核心内容。通过具体示例介绍SQL基本语法和常用聚合函数,帮助读者快速掌握SQL编程技巧。发布于2024年7月19日。
174 7