首页 > 其他分享 >基础知识总结02

基础知识总结02

时间:2023-02-27 15:45:19浏览次数:35  
标签:02 总结 String int System 基础知识 字符串 println out

Day05

方法
方法是一种语法结构,就是一段功能结构封装在一个方法中。方便重复调用。
具有特殊功能的代码块

特殊功能:方法里面的代码写了啥,这个方法就具备什么功能。
代码块:方法整体。
方法创建后并不是直接运行的,需要手动使用后执行,该过程被称为方法调用。

方法的格式

修饰符 返回值类型 方法名(参数列表){
方法体
return 结果;
}
修饰符:public static
返回值类型:
	作用:
		1.告诉调用者,调用该方法会返回一个什么类型的结果
		2.限制编写者,在方法中必须return一个对应类型的结果
	有返回值类型:可以返回任意类型
	无返回值类型:void
方法名:用来调用方法
参数列表:
	调用者调用方法时,用来传递数据给到方法中
	可以让方法更加的灵活
	形参:方法定义时参数列表的参数,没有实际值
	实参:方法调用时,传递的参数,有实际值
return:
	把结果返回给调用者
	提前结束方法

注意
方法必须在main方法里调用运行,因为main方法是程序的入口方法,你不调用在main方法里,你就没有程序运行,而其他方法与方法之间可以互相调用使用。

方法没有被调用的时候,都在方法区中的字节码文件.class中存储,调用jvm会先自动识别main方法,首先将main方法进行压栈,然后依次将需要调用的方法像子弹夹一样进行压栈,当这些方法或程序使用完之后就会进行弹栈,弹出栈内存。

方法的参数传递

基本类型:
	调用方法时,数据值传递,方法内部对传入的数据进行操作,而调用方法的数据不会被改变
	形参变,实参不变
引用类型:
	调用方法时,地址值传递,方法内部对传入的对象中的内容进行操作(改变),而调用方的数据也会跟着变。
	形参变,实参跟着变
	两个方法操作的是同一个对象。

方法执行内存分析如下
image

两个方法操作同一对象的内存分析如下
image

注意
方法调用时,参数的数量与数据类型必须与方法定义中的设置相匹配,否则程序将报错。
方法调用时,如果参数写的是变量名的话,需要提前定义该变量。

方法重载:Overload

在同一个类中,多个方法名相同,参数列表不同的一种现象。
参数不同:
	1. 个数不同
	2. 参数对应的类型不同
    // 编写者:功能类似的方法,可以取相同的方法名。
// 调用者:调用类似的方法,只需要记忆一个方法名即可。

最后搞个栗子:

点击查看代码
public class Demo02 {
    /*
    形参:方法定义时,参数列表的参数,无实际值
    实参:方法调用时,传递的参数,有实际的值。
     */
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        //方法练习
        //1.打印水仙花数
        printNarcissisticNumber();
        System.out.println();
        //2.获取水仙花数的个数
        System.out.println("一共:"+getNarcissisticNumber()+"个");
        //3.获取纸张对折多少次,会超过珠穆朗玛峰的高度的次数,并返回
        System.out.println("一共:"+getPaperFoldTimes()+"次");
        //4.获取任意两个数之间的偶数和
        System.out.println("偶数和为:"+getEvenSum());
        //5.打印任意int数组的所有元素
        int[] array = {1,5,4,8,9,6,3,2};
        printArray(array);
        //6.获取任意int数组的最大值,并返回
        System.out.println("max = "+ getArrayMax(array));
        //7.获取任意int数组的最小值,并返回
        System.out.println("min = "+ getArrayMin(array));
        //8.获取任意int数组的元素和,并返回
        System.out.println("sum = "+ getArraySum(array));
        //9.获取任意int数组的元素平均数,并返回
        System.out.println("avg = "+ getArrayAvg(array));
        //10.定义方法 传入int值作为数组的长,再键盘录入数据,并将数据存入传入的int数组中,最后将数组返回。
        System.out.println("请输入一个正整数作为数组的长度:");
        int length1 = sc.nextInt();
        System.out.println("录入的数组为: "+Arrays.toString(getArray(length1)));
        //11. 定义方法,传入int值作为数组的长,再生成随机数(1-10),并将数据存入传入的int数组中,最后将数组返回。
        System.out.println("请输入一个正整数作为数组的长度:");
        int length2 = sc.nextInt();
        System.out.println("随机生成的数组为: "+Arrays.toString(getArrayRandom(length2)));
        /*
        0.键盘录入一个数,作为数组的长度
		1.随机生成数组长度个(1-100)整数,存入数组中
         */
        System.out.println("请输入一个正整数作为数组的长度:");
        int length3 = sc.nextInt();
        Random r = new Random();
        int[] array3 = new int[length3];
        for (int i = 0; i < array3.length; i++) {
            System.out.println("随机生成了数组第 "+ (i+1) +"个值");
            array3[i] = r.nextInt(100);
        }
        System.out.println("打印数组为:"+Arrays.toString(array3));
        //2.定义一个方法将【奇数】放在数组的【左侧】,【偶数】放在数组的【右侧】
        int[] putArray = putLAndR(array3);
        //3.定义一个方法打印原数组和处理后的数组
        printTwoArray(array3,putArray);
        //4.在将数组最后一个角标为奇数的元素和数组中第一个角标为奇数的元素交换
        int[] changArray = changArray(putArray);
        //5.再次打印原数组和处理后的数组
        printTwoArray(putArray,changArray);

        //6.定义一个方法传入一个int类型数组,输出这个数组中只出现一次的【数字】
        int[] test = {1,22,2,2,3,4,4,5};
        printOnceNum(test);
    }

    private static void printOnceNum(int[] putArray) {
        int count = 0;
        for (int i = 0; i < putArray.length; i++) {
            for (int j = 0; j < putArray.length; j++) {
                if (putArray[i] == putArray[j]){
                    count++;
                }
            }
            if (count == 1){
                System.out.println(putArray[i]+"只出现一次 ");
                count = 0;
            }else {
                count = 0;
                continue;
            }
        }
    }

    private static int[] changArray(int[] putArray) {//0 1 2 3 4 5
        int[] copyArray = new int[putArray.length];//防止原数组变更。
        for (int i = 0; i < copyArray.length; i++) {
            copyArray[i] = putArray[i];
        }
        int temp;
        temp = copyArray[1];
        if (copyArray.length%2==0){
            copyArray[1] = copyArray[copyArray.length-1];
            copyArray[copyArray.length-1] = temp;
        }else {
            copyArray[1] = copyArray[copyArray.length-2];
            copyArray[copyArray.length-2] = temp;
        }
        return copyArray;
    }

    private static void printTwoArray(int[] array3,int[] putArray) {
        System.out.println("打印原数组为:"+Arrays.toString(array3));
        System.out.println("打印新数组为:"+Arrays.toString(putArray));
    }

    private static int[] putLAndR(int[] array3) {
        int[] copyArray = new int[array3.length];
        int flagRight = 0;
        int flagLeft = 0;
        for (int i = 0; i < array3.length; i++) {
            if (array3[i]%2 == 0){
                copyArray[copyArray.length-1-flagRight] = array3[i];
                flagRight++;
            }else {
                copyArray[flagLeft] = array3[i];
                flagLeft++;
            }
        }
        return copyArray;
    }

    private static int[] getArrayRandom(int length2) {
        Random r = new Random();
        int[] array = new int[length2];
        for (int i = 0; i < array.length; i++) {
            System.out.println("随机生成了数组第 "+ (i+1) +"个值");
            array[i] = r.nextInt(10);
        }
        return array;
    }

    private static int[] getArray(int length1) {
        Scanner sc = new Scanner(System.in);
        int[] array = new int[length1];
        for (int i = 0; i < array.length; i++) {
            System.out.println("请输入数组第 "+ (i+1) +"个值");
            array[i] = sc.nextInt();
        }
        return array;
    }

    private static double getArrayAvg(int[] array) {
        int sum = 0;
        double avg = 0;
        for (int i = 0; i < array.length; i++) {
            sum+=array[i];
        }
        avg = (double) sum/array.length;
        return avg;
    }

    private static int getArraySum(int[] array) {
        int sum = 0;
        for (int i = 0; i < array.length; i++) {
            sum+=array[i];
        }
        return sum;
    }

    private static int getArrayMin(int[] array) {
        int min = array[0];
        for (int i = 0; i < array.length; i++) {
            if (min > array[i]){
                min = array[i];//更新最小值
            }
        }
        return min;
    }

    private static int getArrayMax(int[] array) {
        int max = array[0];
        for (int i = 0; i < array.length; i++) {
            if (max < array[i]){
                max = array[i];//更新最大值
            }
        }
        return max;
    }

    private static void printArray(int[] array) {
        for (int i = 0; i < array.length; i++) {
            System.out.print(array[i]+" ");
        }
        System.out.println();
        System.out.println(Arrays.toString(array));
    }

    private static int getEvenSum() {
        Scanner sc = new Scanner(System.in);
        int evenSum = 0;
        while (true) {
        System.out.println("请输入任意两个整数");
        int a = sc.nextInt();
        int b = sc.nextInt();
            if(a>b && a!=b){
                for (int i = b; i <= a; i++){
                    if (i%2==0){
                        evenSum+=i;
                    }else {
                        continue;
                    }
                }
            }else if (a < b && a!=b){
                for (int i = a; i <= b; i++){
                    if (i%2==0){
                        evenSum+=i;
                    }else {
                        continue;
                    }
                }
            }else {
                System.out.println("请输入两个不同的数!");
            }
            System.out.println("是否结束程序");
            System.out.println("否:输入1      是: 输入2");
            int flag = sc.nextInt();
            if(flag ==1){
                System.out.println("程序继续");
                evenSum = 0;
                continue;
            }else if(flag == 2){
                break;
            }else {
                System.out.println("请输入正确命令");
            }

        }
        return evenSum;
    }

    private static int getPaperFoldTimes() {
        double height = 88488600;
        double paper = 1;
        int count = 0;
        while (true){
            paper*=2;
            count++;
            if (paper>=height){
                break;
            }
        }
        return count;
    }

    private static void printNarcissisticNumber() {
        for (int i = 100; i < 1000; i++) {
            int g = i%10;
            int s = i/10%10;
            int b = i/100;
            if (i == g*g*g+s*s*s+b*b*b){
                System.out.print(i+" ");
            }
        }
    }

    private static int getNarcissisticNumber() {
        int count = 0;
        for (int i = 100; i < 1000; i++) {
            int g = i%10;
            int s = i/10%10;
            int b = i/100;
            if (i == g*g*g+s*s*s+b*b*b){
                System.out.print(i+" ");
                count++;
            }
        }
        System.out.println();
        return count;
    }
}

[-------------------------------我是分割线-----------------------------------]

Day07

面向对象基础

概念:
要理解面向对象的思想,得先弄清楚什么是对象。
《java编程思想》中提到了“万物皆为对象”的概念。它将对象视为一种奇特的变量,它除了可以存储数据之外还可以对它自身进行操作。它能够直接反映现实生活中的事物,例如人、车、小鸟等,将其表示为程序中的对象。每个对象都具有各自的状态特征(属性)及行为特征(方法),java就是通过对象之间行为的交互来解决问题的。
面向对象就是把构成问题的事物分解成一个个对象,建立对象不是为了实现一个步骤,而是为了描述某个事物在解决问题中的行为。
类(class)是面向对象中的一个很重要的概念,因为类是很多具有相同属性和行为特征的对象所抽象出来的,对象是类的一个实例。(封装,继承,多态之后再记录)
对象是根据类创建出来的,一定要先有类,才能实例化一个对象。
好处:

1. 更符合我们日常生活的行为习惯
2. 将复杂的事情,变得简单
3. 我们从执行者,变成指挥者

类分类:

功能型
	Scanner
		扫描器
		可以扫描键盘
		还可以扫描文件
	Random
		生成随机数
封装数据
	Student
		封装学生数据
	Phone
		封装手机数据
	前端要展示这些数据

变量

变量的使用遵循就近原则。
局部变量

定义位置:
	定义在方法中,或者方法的参数
内存位置:
	属于方法,而方法在栈中执行,所以他属于栈。
生命周期:
	随着方法的调用而存在,随着方法的弹栈而消失。
默认值:
	没有。使用前必须赋值

成员变量:

定义位置:
	定义在类中方法外
内存位置:
	属于对象,而对象在堆中存放,所以他属于堆。
生命周期:
	随着对象的创建而存在,随着对象被垃圾回收器回收而消失。
默认值:
	有默认值
		整型:0
		浮点:0.0
		字符:' '
		布尔:false
		引用:null

构造方法:

就是用来创建对象的方法

创建对象的同时,可以给成员变量赋值
格式:修饰符  类名(){}
注意:
	1. 构造方法名,必须同类名相同
	2. 不能有返回值类型,void也不能写。
	3. 创建对象时,自动调用,无法通过对象再次调用
	4. 可以重载
	5. 不写任何构造方法,人家送一个
	6. 写了任何构造方法,不再送

部分关键字

private

私有
确保类中成员变量的安全。
不私有,外界可以直接调用成员变量来操作。
提供间接的方式,供外界使用
	setXxx() 赋值
	getXxx() 获取

this

本类对象的引用(地址值)
谁调用我,我就代表谁
作用:区分同名的成员变量和局部变量

封装

就是封起来装好
对外隐藏实现细节,暴露公共的访问方式
提高代码的复用性和安全性
类:封装了方法和变量
方法:封装了代码
private: 封装了变量

代码示例:

点击查看代码
public class Phone {
    String brand;
    int price;
    String ram;
    private int disk;//私有,让外界访问数据不安全,所以可以给外界提供方法set and get
    //构造方法:侧重于初始化,创建对象,同时顺带给成员变量赋值
    //只能是在创建对象时自动调用一次,之后不能通过对象再次调用了
    //可以在构造方法中写return ,return可以提前结束方法
    //构造方法的定义不能写返回值类型,连void都不能写


    public Phone() {
    }

    public Phone(String brand, int price, String ram, int disk) {
        this.brand = brand;
        this.price = price;
        this.ram = ram;
        this.disk = disk;
    }

    public void show(){
        System.out.println(this);//this关键字代表当前类的引用对象的地址值(谁调用代表谁)
    }
    public void setDisk(int disk){
        if (disk >= 32 && disk <=512 ){
            this.disk = disk;
        }else{
            this.disk = 32;
        }
    }
    public int getDisk(){
        return disk;
    }

    public void call() {
        System.out.println("call");
    }
    public void watch(){
        System.out.println("watch");
    }
}

public class Demo01 {
    public static void main(String[] args) {
        //创建对象(实例化)
        Phone p = new Phone();//通过地址值关联
        System.out.println(p);
        //成员变量有默认值,同数组一样
        System.out.println(p.brand);
        System.out.println(p.price);
        System.out.println(p.ram);
        p.brand = "IPhone 14";
        p.price = 15662;
        p.ram = "1T";
        p.setDisk(56);
        p.setDisk(16);
        System.out.println(p.brand);
        System.out.println(p.price);
        System.out.println(p.ram);
        System.out.println(p.getDisk());
        p.show();
    }
}

[--------------------------分割线--------------------------]

Day08

一、今日内容介绍、API概述

各位同学,我们前面已经学习了面向对象编程,使用面向编程这个套路,我们需要自己写类,然后创建对象来解决问题。但是在以后的实际开发中,更多的时候,我们是利用面向编程这种套路,使用别人已经写好的类来编程的。

这就是我们今天要学习的内容——常用API(全称是Application Program Interface 应用程序接口),说人话就是:别人写好的一些程序,给咱们程序员直接拿去调用。

Java官方其实已经给我们写好了很多很多类,每一个类中又提供了一系列方法来解决与这个类相关的问题。

  • 比如String类,表示字符串,提供的方法全都是对字符串操作的。
  • 比如ArrayList类,表示一个容器,提供的方法都是对容器中的数据进行操作的。

像这样的类还有很多,Java把这些类是干什么用的、类中的每一个方法是什么含义,编写成了文档,我们把这个文档称之为API文档。

  1. 我们为什么要学习别人写好的程序呢?

     在行业中有这么一句话:“不要重复造轮子”。这里所说的轮子就是别人已经写过的程序。意思就是不要写重复的程序,因为程序是用来解决问题的,如果这个问题别人已经解决过,并且这个解决方案也得到了市场认可,那就不用再自己重复写这个程序了。
    
     Java已经发展了20多年,在这20多年里,已经积累类了很多问题的解决方案,基本上现在我们遇到的问题,在这20多年里,早就有人解决过。
    
     所以我们把面向对象的高级知识学习完之后,Java语言的语法知识就已经学习完了。剩下的所有内容都是是学习一个一个的API,通过调用API提供的方法来解决实际问题。
    
  2. 我们要学习哪些API

Java的API文档中,有那么多的类,是所有的类都要学习吗?并不是 ,虽然Java提供了很多个类,但是并不是所有类都得到了市场认可,我们只学习一些在工作中常用的就行。

除了Java官方提供的API,还一些第三方的公司或者组织也会提供一些API,甚至比Java官方提供的API更好用,在需要的时候我们也会告诉大家怎么用。

  1. 今天我们主要学习两个类,一个是String类、还有一个是ArrayList类。

字符串的应用场景是非常多的,可以说是无处不在。

比如,在用户登录时,需要对用户名和密码进行校验,这里的用户名和密码都是String

再比如,在和网友聊天时,其实输入的文字就是一个一个字符串

再比如,在百度上搜索时,搜素的关键词,也是字符串

学习完String类之后,还会学习一个类ArrayList

大家知道数组是一个容器,有数组干嘛还要集合呢? 因为数字的长度是固定的,一旦创建不可改变。

比如数组的长度为3,想要存储第4个元素就存不进去了。

使用集合就可以解决上面的问题,集合可以根据需要想存多少个元素就存多少个元素。

二、包

  1. 什么是包

在学习API类之前,我们先要学习包。因为Java官方提供的类有很多,为了对这些类进行分门别类的管理,别人把写好的类都是放在不同的包里的。

包其实类似于文件夹,一个包中可以放多个类文件。

建包的语法格式:

//类文件的第一行定义包
package com.itheima.javabean;

public class 类名{
    
}
  1. 在自己的程序中,调用其他包中的程序,需要注意下面一个问题
  • 如果当前程序中,要调用自己所在包下的其他程序,可以直接调用。(同一个包下的类,互相可以直接调用)
  • 如果当前程序中,要调用其他包下的程序,则必须在当前程序中导包, 才可以访问!
    导包格式:import 包名.类名
  • 如果当前程序中,要调用Java.lang包下的程序,不需要我们导包的,可以直接使用。
  • 如果当前程序中,要调用多个不同包下的程序,而这些程序名正好一样,此时默认只能导入一个程序,另一个程序必须带包名访问。

三、String类

  1. String类概述

各位同学,接下来我们学习String这个类,也就是学对字符串进行处理。为什么要学习字符串处理呢?因为在开发中对于字符串的处理还是非常常见的。

比如:在用户登录时,用户输入的用户名和密码送到后台,需要和正确的用户名和密码进行校验,这就需要用到String类提供的比较功能。

再比如:同学们在直播留言时,有些小伙伴可能不太文明说了一些脏话,后台检测到你输入的是脏话,就会用***把脏话屏蔽掉。这也需要用到String类提供的替换功能

Java为了方便我们处理字符串,所以给我们提供了一个String类来代表字符串,这个类就是java.lang包下。

按照面向对象的编程思想,对于字符串的操作,只需要创建字符串对象,用字符串对象封装字符串数据,然后调用String类的方法就可以了。


  1. String创建对象

接下来我们打开String类的API,看一下String类的对象如何创建。如下图所示
image

String类的API中,有这么一句话:“Java程序中的所有字符串字面值(如"abc")都是字符串的实例实现”。这里所说的实例实现,其实指的就是字符串对象。

意思就是:所有Java的字符串字面值,都是字符串对象。

  • 所以创建String对象的第一种方式就有了

    String s1 = "abc"; //这里"abc"就是一个字符串对象,用s1变量接收

    String s2 = "黑马程序员"; //这里的“黑马程序员”也是一个字符串对象,用s2变量接收

  • 创建String对象还有第二种方式,就是利用String类的构造方法创建String类的对象。

image

我们前面学习过类的构造方法,执行构造方法需要用到new关键字。new String(参数)就是在执行String类的构造方法。

下面我们演示通过String类的构造方法,创建String类的对象

// 1、直接双引号得到字符串对象,封装字符串数据
String name = "黑马666";
System.out.println(name);

// 2、new String创建字符串对象,并调用构造器初始化字符串
String rs1 = new String();
System.out.println(rs1); // ""

String rs2 = new String("itheima");
System.out.println(rs2);

char[] chars = {'a', '黑', '马'};
String rs3 = new String(chars);
System.out.println(rs3);

byte[] bytes = {97, 98, 99};
String rs4 = new String(bytes);
System.out.println(rs4);

关于String类是用来干什么的,以及String类对象的创建我们就学习到这里。最后总结一下

1. String是什么,可以做什么?
	答:String代表字符串,可以用来创建对象封装字符串数据,并对其进行处理。

2.String类创建对象封装字符串数据的方式有几种?
	方式一: 直接使用双引号“...” 。
	方式二:new String类,调用构造器初始化字符串对象。
  1. String类的常用方法

各位同学,在上一节课中,我们学习了如何通过字符串对象封装数据,接下来我们学习调用String类的方法对象字符串数据进行处理。

这里已经将String类的常用方法,给同学们挑出来了,我们先快速的认识一下。为什么是快速认识一下呢?因为API真正的作用是来解决业务需求的,如果不解决业务需求,只是记API是很难记住的。

image

所以API的正确打开方式是,先找到这个类,把这个类中的方法先用代码快速过一遍,有一个大概印象就行。然后再具体的案例中,选择你需要的方法来用就行。

下面我们就把String类中的方法,按照方法的调用规则,先快速过一遍。(注意:第一次调用API方法,都是看着API方法来调用用的,不是背的)

public class StringDemo2 {
    public static void main(String[] args) {
        //目标:快速熟悉String提供的处理字符串的常用方法。
        String s = "黑马Java";
        // 1、获取字符串的长度
        System.out.println(s.length());

        // 2、提取字符串中某个索引位置处的字符
        char c = s.charAt(1);
        System.out.println(c);

        // 字符串的遍历
        for (int i = 0; i < s.length(); i++) {
            // i = 0 1 2 3 4 5
            char ch = s.charAt(i);
            System.out.println(ch);
        }

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

        // 3、把字符串转换成字符数组,再进行遍历
        char[] chars = s.toCharArray();
        for (int i = 0; i < chars.length; i++) {
            System.out.println(chars[i]);
        }

        // 4、判断字符串内容,内容一样就返回true
        String s1 = new String("黑马");
        String s2 = new String("黑马");
        System.out.println(s1 == s2); // false
        System.out.println(s1.equals(s2)); // true

        // 5、忽略大小写比较字符串内容
        String c1 = "34AeFG";
        String c2 = "34aEfg";
        System.out.println(c1.equals(c2)); // false
        System.out.println(c1.equalsIgnoreCase(c2)); // true

        // 6、截取字符串内容 (包前不包后的)
        String s3 = "Java是最好的编程语言之一";
        String rs = s3.substring(0, 8);
        System.out.println(rs);

        // 7、从当前索引位置一直截取到字符串的末尾
        String rs2 = s3.substring(5);
        System.out.println(rs2);

        // 8、把字符串中的某个内容替换成新内容,并返回新的字符串对象给我们
        String info = "这个电影简直是个垃圾,垃圾电影!!";
        String rs3 = info.replace("垃圾", "**");
        System.out.println(rs3);

        // 9、判断字符串中是否包含某个关键字
        String info2 = "Java是最好的编程语言之一,我爱Java,Java不爱我!";
        System.out.println(info2.contains("Java"));
        System.out.println(info2.contains("java"));
        System.out.println(info2.contains("Java2"));

        // 10、判断字符串是否以某个字符串开头。
        String rs4 = "张三丰";
        System.out.println(rs4.startsWith("张"));
        System.out.println(rs4.startsWith("张三"));
        System.out.println(rs4.startsWith("张三2"));

        // 11、把字符串按照某个指定内容分割成多个字符串,放到一个字符串数组中返回给我们
        String rs5 = "张无忌,周芷若,殷素素,赵敏";
        String[] names = rs5.split(",");
        for (int i = 0; i < names.length; i++) {
            System.out.println(names[i]);
        }
    }
}

演示完String类的这些方法之后,我们对字符串有哪些方法,就已经有一个大致印象了。至少知道String字符串能干哪些事情。

至于String类的这些方法是否都记住了,这个还需要通过一些案例训练,在用的过程中去找哪个方法能够解决你的实际需求,就用哪个方法。同一个方法用的次数多个,自然就记住了。

  1. String的注意事项

在上一节,我们学习了字符串的一些常用方法,在实际工作中用这些方法解决字符串的常见问题是完全足够的,但是在面试时可能会问一些原理性的东西。

所以把字符串原理性的内容,就当做注意事项来学习一下。一共有下面的2点:

image

  • 注意事项1:String类的对象是不可变的对象

我们先看一段代码,分析这段代码的结果

image

以上代码中,先定义了一个String变量 name第一次赋值为“黑马”; 然后对name变量记录的字符串进行两次拼接,第一次拼接“程序员”,第二次拼接“播妞”;我们发现得到的结果是:黑马程序员播妞

这里问题就来了,你不是是说:String类的对象是不可变的字符串对象吗?我看name的值变了呀!!!

下面我们就解释一下,String是不可变对象到底是什么含义。

需要注意的是:只要是以“”方式写出的字符串对象,会在堆内存中的字符串常量池中存储。

执行第一句话时,会在堆内存的常量池中,创建一个字符串对象“黑马”,然后把“黑马”的地址赋值给String name

image

当执行第二句话时,又会再堆内存的常量池中创建一个字符串“程序员”,和“黑马”拼接,拼接之后还会产生一个新的字符串对象”黑马程序员“,然后将新产生的“黑马程序员”对象的地址赋值给String name变量。

image

此时你会发现,之前创建的字符串对象“黑马”内容确实是没有改变的。所以说String的对象是不可变的。

  • 注意事项2:字符串字面量和new出来字符串的区别
    1. 只要是以“...”方式写出的字符串对象,会存储到字符串常量池,且相同内容的字符串只存储一份。如下图一所示
    2. 但通过new方式创建字符串对象,每new一次都会产生一个新的对象放在堆内存中。如下图二所示

image

image

  • 总结一下,字符串的注意事项。

    1. String是不可变字符串对象
    2. 只要是以“...”方式写出的字符串对象,会存储到字符串常量池,且相同内容的字符串只存储一份;
    3. 但通过new方式创建字符串对象,每new一次都会产生一个新的对象放在堆内存中。
  1. String案例一:用户登录案例

接下来给大家做一个案例,使用字符串的功能完成登录案例。案例需求如下:

image

分析一下完成案例的步骤:
	1.首先,从登录界面上可以得出,需要让用户输入登录名和密码
	2.设计一个登录方法,对用户名和密码进行校验
	3.调用登录方法,根据方法的返回结果,判断登录是否成功。
	4.如果登录失败,循环登录3次,结束循环;如果登录成功,跳出循环;

案例分析的步骤完成代码

/**
   目标:完成用户的登录案例。
 */
public class StringTest4 {
    public static void main(String[] args) {
        // 1、开发一个登录界面
        for (int i = 0; i < 3; i++) {
            Scanner sc = new Scanner(System.in);
            System.out.println("请您输入登录名称:");
            String loginName = sc.next();
            System.out.println("请您输入登录密码:");
            String passWord = sc.next();

            // 5、开始调用登录方法,判断是否登录成功
            boolean rs = login(loginName, passWord);
            if(rs){
                System.out.println("恭喜您,欢迎进入系统~~");
                break; // 跳出for循环,代表登录完成
            }else {
                System.out.println("登录名或者密码错误,请您确认~~");
            }
        }
    }

    /**
      2、开发一个登录方法,接收用户的登录名和密码,返回认证的结果
     */
    public static boolean login(String loginName, String passWord){
        // 3、准备一份系统正确的登录名和密码
        String okLoginName = "itheima";
        String okPassWord = "123456";

        // 4、开始正式判断用户是否登录成功
        /*if(okLoginName.equals(loginName) && okPassWord.equals(passWord)){
            // 登录成功的
            return true;
        }else {
            return false;
        }*/
        return okLoginName.equals(loginName) && okPassWord.equals(passWord);
    }
}
  1. String案例二:随机产生验证码

接下来学习一个再工作中也比较常见的案例,使用String来开发验证码。需求如下:

image

根据需求分析,步骤如下:
	1.首先,设计一个方法,该方法接收一个整型参数,最终要返回对应位数的随机验证码。
	2.方法内定义2个字符串变量:
		1个用来记住生成的验证码,1个用来记住要用到的全部字符。
	3.定义for循环控制生成多少位随机字符
	4.每次得到一个字符范围内的随机索引
	5.根据索引提取该字符,把该字符交给code变量连接起
	6.循环结束后,在循环外返回code即可。
	7.在主方法中调用生成验证码的方法

根据步骤完成代码

import java.util.Random;
/**
    目标:完成随机产生验证码,验证码的每位可能是数字、大写字母、小写字母
 */
public class StringTest5 {
    public static void main(String[] args) {
        System.out.println(createCode(4));
        System.out.println(createCode(6));
    }
    /**
       1、设计一个方法,返回指定位数的验证码
     */
    public static String createCode(int n){
        // 2、定义2个变量 
        //一个是记住最终产生的随机验证码 
        //一个是记住可能用到的全部字符
        String code = "";
        String data = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";

        Random r = new Random();
        // 3、开始定义一个循环产生每位随机字符
        for (int i = 0; i < n; i++) {
            // 4、随机一个字符范围内的索引。
            int index = r.nextInt(data.length());
            // 5、根据索引去全部字符中提取该字符
            code += data.charAt(index); // code = code + 字符
        }
        // 6、返回code即可
        return code;
    }
}

关于String的案例,我们先练习到这里。以后遇到对字符串进行操作的需求,优先找String类有没有提供对应的方法。

四、ArrayList类

  1. ArrayList快速入门

学习完String类之后,接下来再学习一个类——叫ArrayList。

ArrayList表示一种集合,它是一个容器,用来装数据的,类似于数组。那有了数组,为什么要有集合呢?

因为数组一旦创建大小不变,比如创建一个长度为3的数组,就只能存储3个元素,想要存储第4个元素就不行。而集合是大小可变的,想要存储几个元素就存储几个元素,在实际工作中用得更多。

然后集合有很多种,而ArrayList只是众多集合中的一种,跟多的集合我们在就业班的课程中再学习。如下图所示:
image

集合该怎么学呢?1. 首先你要会创建集合对象,2. 然后能够调用集合提供的方法对容器中的数据进行增删改查,3. 最后知道集合的一些特点就可以了。

image

  1. ArrayList常用方法

想要使用ArrayList存储数据,并对数据进行操作:

  • 第一步:创建ArrayList容器对象。一般使用空参数构造方法,如下图所示:
  • 第二步:调用ArrayList类的常用方法对容器中的数据进行操作。常用方法如下:

image

接下来我们把ArrayList集合的这些方法快速的熟悉一下:

/**
目标:要求同学们掌握如何创建ArrayList集合的对象,并熟悉ArrayList提供的常用方法。
 */
public class ArrayListDemo1 {
    public static void main(String[] args) {
        // 1、创建一个ArrayList的集合对象
        // ArrayList<String> list = new ArrayList<String>();
        // 从jdk 1.7开始才支持的
        ArrayList<String> list = new ArrayList<>();

        list.add("黑马");
        list.add("黑马");
        list.add("Java");
        System.out.println(list);

        // 2、往集合中的某个索引位置处添加一个数据
        list.add(1, "MySQL");
        System.out.println(list);

        // 3、根据索引获取集合中某个索引位置处的值
        String rs = list.get(1);
        System.out.println(rs);

        // 4、获取集合的大小(返回集合中存储的元素个数)
        System.out.println(list.size());

        // 5、根据索引删除集合中的某个元素值,会返回被删除的元素值给我们
        System.out.println(list.remove(1));
        System.out.println(list);

        // 6、直接删除某个元素值,删除成功会返回true,反之
        System.out.println(list.remove("Java"));
        System.out.println(list);

        list.add(1, "html");
        System.out.println(list);

        // 默认删除的是第一次出现的这个黑马的数据的
        System.out.println(list.remove("黑马"));
        System.out.println(list);

        // 7、修改某个索引位置处的数据,修改后会返回原来的值给我们
        System.out.println(list.set(1, "黑马程序员"));
        System.out.println(list);
    }
}
  1. ArrayList应用案例1

接下来,我们学习一个ArrayList的应用案例,需求如下:

image

我们分析一下这个案例的步骤该如何实现:

1.用户可以选购多个商品,可以创建一个ArrayList集合,存储这些商品
2.按照需求,如果用户选择了"枸杞"批量删除,应该删除包含"枸杞"的所有元素
	1)这时应该遍历集合中每一个String类型的元素
	2)使用String类的方法contains判断字符串中是否包含"枸杞"
    3)包含就把元素删除
3.输出集合中的元素,看是否包含"枸杞"的元素全部删除

按照分析的步骤,完成代码

public class ArrayListTest2 {
    public static void main(String[] args) {
        // 1、创建一个ArrayList集合对象
        ArrayList<String> list = new ArrayList<>();
        list.add("枸杞");
        list.add("Java入门");
        list.add("宁夏枸杞");
        list.add("黑枸杞");
        list.add("人字拖");
        list.add("特级枸杞");
        list.add("枸杞子");
        System.out.println(list);
        //运行结果如下: [Java入门, 宁夏枸杞, 黑枸杞, 人字拖, 特级枸杞, 枸杞子]
       
        // 2、开始完成需求:从集合中找出包含枸杞的数据并删除它
        for (int i = 0; i < list.size(); i++) {
            // i = 0 1 2 3 4 5
            // 取出当前遍历到的数据
            String ele = list.get(i);
            // 判断这个数据中包含枸杞
            if(ele.contains("枸杞")){
                // 直接从集合中删除该数据
                list.remove(ele);
            }
        }
        System.out.println(list);
        //删除后结果如下:[Java入门, 黑枸杞, 人字拖, 枸杞子]
    }
}

运行完上面代码,我们会发现,删除后的集合中,竟然还有黑枸杞,枸杞子在集合中。这是为什么呢?

image

枸杞子被保留下来,原理是一样的。可以自行分析。

那如何解决这个问题呢?这里打算给大家提供两种解决方案:

  • 集合删除元素方式一:每次删除完元素后,让控制循环的变量i--就可以了;如下图所示

image

具体代码如下:

// 方式一:每次删除一个数据后,就让i往左边退一步
for (int i = 0; i < list.size(); i++) {
    // i = 0 1 2 3 4 5
    // 取出当前遍历到的数据
    String ele = list.get(i);
    // 判断这个数据中包含枸杞
    if(ele.contains("枸杞")){
        // 直接从集合中删除该数据
        list.remove(ele);
        i--;
    }
}
System.out.println(list);
  • 集合删除元素方式二:我们只需要倒着遍历集合,在遍历过程中删除元素就可以了

image

image

image

image

具体代码如下:

// 方式二:从集合的后面倒着遍历并删除
// [Java入门, 人字拖]
//   i
for (int i = list.size() - 1; i >= 0; i--) {
    // 取出当前遍历到的数据
    String ele = list.get(i);
    // 判断这个数据中包含枸杞
    if(ele.contains("枸杞")){
        // 直接从集合中删除该数据
        list.remove(ele);
    }
}
System.out.println(list);
  1. ArrayList应用案例2

各位同学,上一个ArrayList应用案例中,我们往集合存储的元素是String类型的元素,实际上在工作中我们经常往集合中自定义存储对象。

接下来我们做个案例,用来往集合中存储自定义的对象,先阅读下面的案例需求:

image

分析需求发现:

  1. 在外卖系统中,每一份菜都包含,菜品的名称、菜品的原价、菜品的优惠价、菜品的其他信息。那我们就可以定义一个菜品类(Food类),用来描述每一个菜品对象要封装那些数据。
  2. 接着再写一个菜品管理类(FoodManager类),提供展示操作界面、上架菜品、浏览菜品的功能。
  • 首先我们先定义一个菜品类(Food类),用来描述每一个菜品对象要封装那些数据。

    public class Food {
    private String name; //菜品名称
    private double originalPrice; //菜品原价
    private double specialPrice; //菜品优惠价
    private String info; //菜品其他信息

      public Food() {
      }
    
      public Food(String name, double originalPrice, double specialPrice, String info) {
          this.name = name;
          this.originalPrice = originalPrice;
          this.specialPrice = specialPrice;
          this.info = info;
      }
    
      public String getName() {
          return name;
      }
    
      public void setName(String name) {
          this.name = name;
      }
    
      public double getOriginalPrice() {
          return originalPrice;
      }
    
      public void setOriginalPrice(double originalPrice) {
          this.originalPrice = originalPrice;
      }
    
      public double getSpecialPrice() {
          return specialPrice;
      }
    
      public void setSpecialPrice(double specialPrice) {
          this.specialPrice = specialPrice;
      }
    
      public String getInfo() {
          return info;
      }
    
      public void setInfo(String info) {
          this.info = info;
      }
    

    }

  • 接下来写一个菜品管理类,提供上架菜品的功能、浏览菜品的功能、展示操作界面的功能。

    public class FoodManager{
    //为了存储多个菜品,预先创建一个ArrayList集合;
    //上架菜品时,其实就是往集合中添加菜品对象
    //浏览菜品时,其实就是遍历集合中的菜品对象,并打印菜品对象的属性信息。
    private ArrayList foods = new ArrayList<>();
    //为了在下面的多个方法中,能够使用键盘录入,提前把Scanner对象创建好;
    private Scanner sc = new Scanner(System.in);

      /**
       1、商家上架菜品
       */
      public void add(){
          System.out.println("===菜品上架==");
          // 2、提前创建一个菜品对象,用于封装用户上架的菜品信息
          Food food = new Food();
          System.out.println("请您输入上架菜品的名称:");
          String name = sc.next();
          food.setName(name);
    
          System.out.println("请您输入上架菜品的原价:");
          double originalPrice = sc.nextDouble();
          food.setOriginalPrice(originalPrice);
    
          System.out.println("请您输入上架菜品的优惠价:");
          double specialPrice = sc.nextDouble();
          food.setSpecialPrice(specialPrice);
    
          System.out.println("请您输入上架菜品的其他信息:");
          String info = sc.next();
          food.setInfo(info);
    
          // 3、把菜品对象添加到集合容器中去
          foods.add(food);
          System.out.println("恭喜您,上架成功~~~");
      }
    
      /**
         2、菜品;浏览功能
       */
      public void printAllFoods(){
          System.out.println("==当前菜品信息如下:==");
          for (int i = 0; i < foods.size(); i++) {
              Food food = foods.get(i);
              System.out.println("菜品名称:" + food.getName());
              System.out.println("菜品原价:" + food.getOriginalPrice());
              System.out.println("菜品优惠价:" + food.getSpecialPrice());
              System.out.println("其他描述信息:" + food.getInfo());
              System.out.println("------------------------");
          }
      }
      /**
      3、专门负责展示系统界面的
      */
      public void start(){
          while (true) {
              System.out.println("====欢迎进入商家后台管理系统=====");
              System.out.println("1、上架菜品(add)");
              System.out.println("2、浏览菜品(query)");
              System.out.println("3、退出系统(exit)");
              System.out.println("请您选择操作命令:");
              String command = sc.next();
              switch (command) {
                  case "add":
                      add();
                      break;
                  case "query":
                      printAllFoods();
                      break;
                  case "exit":
                      return; // 结束当前方法!
                  default:
                      System.out.println("您输入的操作命令有误~~");
              }
          }
      }
    

    }

  • 最后在写一个测试类Test,在测试类中进行测试。其实测试类,只起到一个启动程序的作用。

    public class Test {
    public static void main(String[] args) {
    FoodManager manager = new FoodManager();
    manager.start();
    }
    }

运行结果如下:需要用户输入add、query或者exit,选择进入不同的功能。

image

(ps.下一次就是就业班之后再发了)

标签:02,总结,String,int,System,基础知识,字符串,println,out
From: https://www.cnblogs.com/wjqblog/p/17159123.html

相关文章

  • Kali 2021.3 安装ARL (资产侦察灯塔系统)
    0x00准备工作下载kali镜像:https://www.kali.org/get-kali/ARL:https://github.com/TophantTechnology/ARL0x01Docker安装ARL目前不支持Windows,Linux和Mac建议Docker安......
  • 算法刷题 Day 57 | ● 647. 回文子串 ● 516.最长回文子序列 ● 动态规划总结篇
    详细布置647.回文子串动态规划解决的经典题目,如果没接触过的话,别硬想直接看题解。https://programmercarl.com/0647.%E5%9B%9E%E6%96%87%E5%AD%90%E4%B8%B2.htm......
  • Shiro 身份认证绕过漏洞 CVE-2022-32532
    前言ApacheShiro是一个强大且易用的Java安全框架,通过它可以执行身份验证、授权、密码和会话管理。使用Shiro的易用API,您可以快速、轻松地保护任何应用程序——从最......
  • javascript 高级编程 之 Array 用法总结
    引用类型是一种数据结构,用于将数据和功能联系起来。创建对象的方式:1.new操作符vararray=newArray();2.字面量表示法创建vararray=[];Array检测数组:检测数组......
  • 2023前端一面vue面试题合集
    函数式组件优势和原理函数组件的特点函数式组件需要在声明组件是指定functional:true不需要实例化,所以没有this,this通过render函数的第二个参数context来代替没有生......
  • Go组件库总结之介入式链表
    本篇文章我们用Go封装一个介入式的双向链表,目的是将链表的实现和具体元素解耦。文章参考自:https://github.com/brewlin/net-protocol1.元素的接口typeElementinterface......
  • 2023前端vue面试题汇总
    Vuex有哪几种属性?有五种,分别是State、Getter、Mutation、Action、Modulestate=>基本数据(数据源存放地)getters=>从基本数据派生出来的数据mutations=>提交......
  • 数据结构刷题2023.02.27小记
    单循环链表A从表中任一结点出发都能扫描到整个链表B不再需要头指针了C在进行插入、删除操作时,能更好地保证链表不断开D已知某个结点的位置后,能够容易找到它的直接......
  • 推荐 7 个学习 TypeScript 的宝库,2021 学 TS 看这篇就够了!
    前言猫哥是一个常年混迹在GitHub上的猫星人,所以发现了不少好的前端开源项目、常用技巧,在此分享给大家。公众号:前端GitHub,专注于挖掘GitHub上优秀的前端开源项目,并以......
  • 2023-2-20 #40 只有回音在房间中旋转交织着暮光
    最近停更的主要原因是打模拟赛比较emo,做题也没做几道,就打算屯一起发出来。没想到这么多人想看我博客,那我就整理整理发出来吧!竟然有人怀疑我这些文章是不是闲话啊!!我原本......