首页 > 其他分享 >day08-String和ArrayList

day08-String和ArrayList

时间:2023-02-19 11:44:34浏览次数:34  
标签:day08 java String int ArrayList list 字符串 public

1,基本介绍

介绍两个API: String类和ArrayList类

API(全称Application Programming Interface:应用程序编程接口)

就是别人写好的一些程序,给程序员直接拿去调用即可解决问题的代码类。

什么是包?

包是用来分门别类的管理各种不同程序的,类似于文件夹,建包有利于程序的管理和维护。

在自己程序中调用其他包下的程序的注意事项

  • 如果当前程序中,要调用自己所在包下的其他程序,可以直接调用。(同一个包下的类,互相可以直接调用

  • 如果当前程序中,要调用其他包下的程序,则必须在当前程序中导包, 才可以访问!

    导包格式:import 包名.类名;

  • 如果当前程序中,要调用Java提供的程序,也需要先导包才可以使用;但是Java.lang包下的程序是不需要我们导包的,可以直接使用。

  • 如果当前程序中,要调用多个不同包下的程序,而这些程序名正好一样,此时默认只能导入一个程序,另一个程序必须带包名访问。

image

2,String类

String是java提前写好的一个类,存放在java.lang包下,代表着所有的字符串对象,可以用来封装字符串类型的数据,并提供了很多操作字符串的方法,程序员只需要面向字符串对象,调用这些提前写好的方法,就可以完成很多字符串相关的操作了;

String类的使用步骤:

  1. 想方设法得到一个字符串对象;(用双引号键盘输入String的构造方法等各种手段均可)

  2. 面向字符串对象调用String类中的方法;

  3. 处理方法产出的结果;

String创建对象封装字符串数据的两种方式:

方式一: Java 程序中的所有字符串文字(例如“abc”)都为此类的对象。

String name = "宗介";
String schoolName = "早稻田";

方式二: 调用String类的构造器初始化字符串对象。 一般不使用构造器,太浪费内存,后面会分析

构造器 说明
public String() 创建一个空白字符串对象,不含有任何内容
public String(String original) 根据传入的字符串内容,来创建字符串对象
public String(char[] chars) 根据字符数组的内容,来创建字符串对象
public String(byte[] bytes) 根据字节数组的内容,来创建字符串对象
        String str = "hello";

        String hello = new String();

        String hello = new String("hello");
        System.out.println(hello);

        char[] arr = {'a','b','c'};
        String s = new String(arr);
        System.out.println(s);

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

String提供的操作字符串数据的常用方法: 这些都是最最最常用的一定牢记

方法名 说明
public int length() 获取字符串的长度返回(就是字符个数)
public char charAt(int index) 获取某个索引位置处的字符返回
public char[] toCharArray(): 将当前字符串转换成字符数组返回
public boolean equals(Object anObject) 判断当前字符串与另一个字符串的内容一样,一样返回true
public boolean equalsIgnoreCase(String anotherString) 判断当前字符串与另一个字符串的内容是否一样(忽略大小写)
public String substring(int beginIndex, int endIndex) 根据开始和结束索引进行截取,得到新的字符串(包前不包后)
public String substring(int beginIndex) 从传入的索引处截取,截取到末尾,得到新的字符串返回
public String replace(CharSequence target, CharSequence replacement) 使用新值,将字符串中的旧值替换,得到新的字符串
public boolean contains(CharSequence s) 判断字符串中是否包含了某个字符串
public boolean startsWith(String prefix) 判断字符串是否以某个字符串内容开头,开头返回true,反之
public String[] split(String regex) 把字符串按照某个字符串内容分割,并返回字符串数组回来
public int compareTo(String anotherString) 按字典顺序比较两个字符串。

对于split方法需要特殊的注意: 通过代码展示

//        需求: 想让字符串以 '.' 为切分点进行切分
        String str = "1.2.3";
        String[] split = str.split(".");
        System.out.println(split.length); // 0 这里是0

但是结果却是0 ,为什么?

首先需要了解 正则表达式中的特殊字符:正则表达式中有 15 个元字符,是有特殊意义的,使用时需要转义,这 15 个字符分别是:

 (    [     {    \    ^    -    $     **    }    ]    )    ?    *    +    . 

因为“.” 是特殊字符, 且split是支持正则表达式的,所以正确表示应该是“\\.”

首先介绍一下: ‘.’ 在正则中的意思是 : 匹配除换行符 \n 之外的任何单字符

所以结果为 0 也就解释的通了: 因为这里str.split("."), 是以任何一个字符作为分割,分割完就没了 为0

那么如果想用应该怎么办呢? 转义,告诉java这不是一个特殊字符 通过 \ , 但是会发现 \ 也是一个特殊字符,那么就需要先对\ 进行转义, 即 : \\. 就可以代表普通字符的 ‘.’ , 即代码如下:

String str = "1.2.3";
String[] split1 = str.split("\\.");
System.out.println(split1.length); //  3

另外除了split()还有replace , replaceAll ,这两者都是由正则表达式类库实现的,但是 replace 采用的是字符串原有的意思来替换,而 replaceAll 则是按照正则表达式的字符串来替换

另外对于split()方法还有一个注意的点 , 就是含头不含尾: 示例如下;

String str = "abbaccadda";
String[] as = str.split("a");
for (String a : as) {
    System.out.println(a);
}

结果如下: 切割之后如果前面没有就会保留空行,但是如果后面没有就不在保留. 即 含头不含尾

   //  这里是头
bb
cc
dd

String使用时的注意事项:

第一点:

​ String对象的内容不可改变,被称为不可变字符串对象。

第二点:

​ 只要是以 “ ” 方式写出的字符串对象,会存储到字符串常量池,且相同内容的字符串只存储一份;

​ 但通过new方式创建字符串对象,每new一次都会产生一个新的对象放在堆内存中。

String注意事项1: String的对象是不可变字符串对象 示例如下:

image

内存示意图: 注意常量池和堆的变化 这个图貌似有一点问题,就是常量池在方法区中

image

那么问题又来了,堆中的数据是什么时候new出来的?

现在把目光定睛在常量池中,会发现通过 “ ” 定义的常量都在常量池中,这样的好处是调用同样的名字的时候都指向常量池中的同一个地址,大大的节省了内存。但是如果是两个字符串相加的话,java会自动拼接,设想如果常量池中没有拼接后的就会重新创建,开辟空间,之前存储的也就成为了垃圾,很麻烦且很浪费,所以在后面java内部就是用StringBuilder对象的append完成拼接。API中的具体描述如下:

Java 语言提供对字符串串联符号("+")以及将其他对象转换为字符串的特殊支持。字符串串联是通过 StringBuilder(或 StringBuffer)类及其 append 方法实现的。字符串转换是通过 toString 方法实现的,该方法由 Object 类定义,并可被 Java 中的所有类继承。有关字符串串联和转换的更多信息,请参阅 Gosling、Joy 和 Steele 合著的 The Java Language Specification。 
public static void main(String[] args) {
     String s1 = "我爱";
     String s2 = "java";

     String s3 = s1 + "," + s2;

//   其实 java内部处理是这样子做的
//   String s3 = (new StringBuilder().append(s1).append(",").append(s2).toString());

    }

当知道了java内部的处理变量的机制,那么再看下下面的结果:

image

首先我们知道 == 号对于引用类型比较的是其内存地址,第一个为false我们就很明白,因为在拼接的时候创建了StringBuilder对象使用其append()方法完成的拼接;因为new了所以两者的内存地址肯定不一样,一个在常量池中,一个在堆的普通区中。那么第二个为什么是true呢?
因为Java存在编译优化机制,程序在编译时: “a” + “b” + “c” 会直接转成 abc,以提高程序的执行性能。即如果是常量(字面量拼接的时候,java会做出一些优化,来提高性能.)
这样就显而易见了.

继续来看String类:

    public static void main(String[] args) {
        String str1 = "abc";
        String str2 = new String("abc");

        System.out.println(str1 == str2);   // 
    }

第二行和第三行创建了几个对象:

很明显第二行在堆中的常量池中创建了对象, 第三行,因为堆中有了一模一样的数据,所以就不在在常量池中创建,但是因为new了一个实例,所以在堆中还是会创建一个对象,所以第二行第三行分别创建了一个对象; 又因为两个的指向不同str1指向常量池,str2指向堆中的地址所以肯定不同啦,false;

    public static void main(String[] args) {
        String str1 = new String("abc");
        String str2 = "abc";
        System.out.println(str1 == str2);
    }

这个第二行和第三行创建了几个对象: 分别是两个和零个

首先常量池中一个,其次在在堆中一个,所以两个

第三行,因为常量池中有了相同的常量(字面量), 所以就不在创建直接引用。这也体现了常量池的好处

3,ArrayList类

集合是一种容器,用来装数据的,类似于数组。但集合类是强调通过对象来实现对数据的处理,并且不限制长度会自动的扩容 ,大小可变。

首先介绍一种形式:

ArrayList : 后面的 英文全称是: element 元素

在java中称为泛型: 后面的笔记会提到,在这里我们只需要知道,如果集合中想存什么类型的数据,那么就把 替换成对应的类型即可,且这里面类型只能是引用类型,不能使用基本数据类型,如果想使用需要使用到包装类

构造器:

构造器 说明
public ArrayList() 构造一个初始容量为 10 的空列表。
ArrayList(int initialCapacity) 构造一个具有指定初始容量的空列表。

常用方法:

常用方法名 说明
public boolean add(E e) 将指定的元素添加到此集合的末尾
public void add(int index,E element) 在此集合中的指定位置插入指定的元素
public E get(int index) 返回指定索引处的元素
public int size() 返回集合中的元素的个数
public E remove(int index) 删除指定索引处的元素,返回被删除的元素
public boolean remove(Object o) 删除指定的元素,返回删除是否成功
public E set(int index,E element) 修改指定索引处的元素,返回被修改的元素

代码示例:

    public static void main(String[] args) {
        ArrayList<String> stringList = new ArrayList<>();
//      add(E e)
        stringList.add("芝诺的乌龟");
        stringList.add("拉普拉斯兽");
//      add(int index,E element)  通过索引插入到已有的元素中,索引最大为stringList.size();
        stringList.add(2, "麦克斯韦妖");
        stringList.add(2, "薛定谔的猫");

//        size()获取集合的长度
        int size = stringList.size();
        System.out.println("集合的长度为:" + size);

//        get(int  index)  通过索引获取值
        String str = stringList.get(2);
        System.out.println("2 索引的值为:" + str);

//        set(int index,E element) 修改指定索引处的元素,返回被修改的元素
        String str2 = stringList.set(2, "尼古拉斯的狗");
        System.out.println("2 处的位置修改之前为:" + str2);

//        删除
//        remove(int  index)   删除指定索引处的元素,返回被删除的元素
        String str3 = stringList.remove(2);
        System.out.println("索引为2的" + str3 + "被删除了");


//        remove(Object o)  删除指定的元素,返回删除是否成功
        String name = "芝诺的乌龟";   //   String对象
        boolean remove = stringList.remove(name);
        System.out.println(name + "是否删除:" + remove);
    }

输出结果:

集合的长度为:4
2 索引的值为:薛定谔的猫
2 处的位置修改之前为:薛定谔的猫
索引为2的尼古拉斯的狗被删除了
芝诺的乌龟是否删除:true

最后一个需要特别注意的问题:

在删除的时候,当前一个数据被删除的时候,那么后面的数据会自动的向前补位,代码示例如下:

    public static void main(String[] args) {
//        需求: 删除包含java的所有数据
//        包含,应该想到contains()方法 .删除就是remove() 所有那么就需要遍历了
        ArrayList<String> list = new ArrayList<>();
//        添加数据
        list.add("java从入门到精通");
        list.add("javaWEB基础");
        list.add("mysql从删库到跑路");
        list.add("java语言程序设计");

        for (int i = 0; i < list.size(); i++) {
//            如果包含就删除
            if (list.get(i).contains("java")){
                list.remove(i);
            }
        }
        for (String str : list) {
            System.out.println(str);
        }
    }

不看结果设想一下控制台应该输出什么:

javaWEB基础
mysql从删库到跑路

上面的结果就是因为有两个和java相关的内容紧挨着, 在删除的时候当 前一个被删除了,后一个就不填补空位, 但是这时的 变量i 会自增,从而错过.

找到了问题 , 下面就解决问题.不让 当前一个删除的时候不让 i 自增. 修改后for循环如下:

        for (int i = 0; i < list.size(); i++) {
//            如果包含就删除
            if (list.get(i).contains("java")){
                list.remove(i);
                // 和++ 抵消,相当于不动
                i--;
            }
        }

上面是从索引下手的: 那么我们也可以从原因下手,原因是因为 集合的自动填补空位. 那么我们从后面遍历判断就不会有这种情况了. 循环删除部分代码示例如下:

        for (int i = list.size() - 1; i >= 0; i--) {
            if (list.get(i).contains("java")){
                list.remove(i);
            }
        }

结果如下:

mysql从删库到跑路

2.19 祸不单行的一天依然要加油呀

标签:day08,java,String,int,ArrayList,list,字符串,public
From: https://www.cnblogs.com/yfs1024/p/17134445.html

相关文章

  • C#两个特殊的集合类StringCollection与StringDictionary
    1、前言    为啥要写StringCollection与StringDictionary这两个集合呢?这两个集合都可以存储字符串的数据结构,都是非泛型的可以存储任何类型的数据,都是使用数组存储元......
  • List实现类----ArrayList的使用
    importjava.util.ArrayList;importjava.util.Iterator;importjava.util.ListIterator;publicclassDemo01{publicstaticvoidmain(String[]args){/......
  • ArrayList详解
    ArrayList详解ArrayList是实现了List接口,其内部是基于数组实现的:publicclassArrayList<E>extendsAbstractList<E>implementsList<E>,RandomAccess,Clone......
  • 调用自定义的SplitString函数对字符串进行分割
    voidSplitString(conststd::string&s,std::vector<std::string>&v,conststd::string&c){ std::string::size_typepos1,pos2; pos2=s.find(c); pos1=0; while......
  • CF1037G A Game on Strings Sol
    有趣题。首先"分成若干个互不相干的子串"是子游戏的定义,可以用SG函数处理。然而接下来试着打了半个多小时的表,没有找到任何规律。但是发现SG函数的状态转移是很简单......
  • String之contains方法
    https://blog.csdn.net/qq_41837249/article/details/1160183431 String类型有一个方法:contains(),该方法是判断字符串中是否有子字符串。如果有则返回true,如果没有则返回f......
  • String hashcode()
    Stringhashcode()代码段publicinthashCode(){inth=hash;if(h==0&&value.length>0){charval[]=value;......
  • String
    String概念:String的底层是一个封装的char[]数组特点因为String的底层是char[]数组,所以String的长度不可变创建实例String通常有两种创建实例的方式Stringstr="a......
  • ArrayList
    ArrayList是通过数组实现的,是可变长的数组,与普通数组得区别就是它没有固定的大小限制(动态数组);ArrayList不是线程安全的;ArrayList数组的索引值从0开始。......
  • Java—String类
    一、toString()方法1.publicStringtoString():返回对象的字符串;2.toString(),返回的是对象的地址值,没有实际意义,需要重写;重写规制:返回对象的属性值;getClass.getNam......