String(2)

一)前置知识回顾:

字符串中的库函数,基本上只要对原来的字符串进行修改,基本上返回的都是一个新的对象

String s1=new String("hello");
String s2=new String("world");
String s3=s1;

二)下列程序的输出结果是:输出good和gbc
public class Task {
    String str=new String("good");
    char[] ch={'a','b','c'};
    public static void main(String[] args) {
       Task task=new Task();
       task.change(task.str,task.ch);
       System.out.println(task.str);
       System.out.println(task.ch);
    }
    public void change(String string,char[] ch){
        string="testOK";
        ch[0]='g';
    }
}

1)当没有调用这个change方法之前,我们的函数的内存布局是这样子的:

 2)当我们进行调用这个函数的时候,用形参来进行接受的时候,没有进入到方法之前:

3)进行接收到的形参会在栈上面开辟一块空间,此时string就指向了之前咱们对上面的String对象,咱们的形参的char[]数组指向的是堆中的0X100 

4)进入到方法之后,因为形参的ch和实参的ch都指向同一块内存地址空间,所以形参可以直接根据引用,来进行修改数组的第一块元素位置改成了g

5)但是此时的string指向了一个新的字符串,所以它指向的字符串对象发生了改变,里面的引用所指向的地址也发生了改变

这就是整个内存变化图,由此可知str引用变量里面所指向的对象的地址并没有发生改变,不是说传递引用就一定可以改变原来的值, 而是说你拿着这个引用都做了一些啥样的事情

String中的一些常见方法
1)字符与字符串

1)public String(char value[])属于构造方法,将字符数组的内容变成字符串

2)public String(char[] value,int offset,int count)属于构造方法,将字符数组的部分内容变成字符串

3)public char charAt(int index)获取指定索引位置的字符

       String str="HelloWorld";
       for(int i=0;i<str.length();i++){
           System.out.print(str.charAt(i));
       }
//HelloWorld    

4)public char[] toCharArray()将字符串变成字符数组返回

String str="HelloWorld";
char[] values=str.toCharArray();
System.out.println(Arrays.toString(values));
//[H, e, l, l, o, W, o, r, l, d]

5)返回格式化字符串

String str=String.format("%s %s 我是中国人","我想飞","我想要找一个好工作");
System.out.println(str);

 //1字符数组变成字符串
   char[] arr1={'a','b','c'};//不是双引号引起来的,是不会进行入池的
   String str=new String(arr1);
  //2将部分字节数组的内容变成字符串
  String hh=new String(arr1,1,3);    
  //3字符串变成数组
 String str2="world";
  char[] arr2=str2.toCharArray();     
  //4获取到固定位置的索引的字符
  String dd=new String("lijiawei");
  char ch=dd.charAt(1);
  //判断是否是数字字符还有一种方法
        char ch='0';
        boolean flag=Character.isDigit(ch);
        if(flag==false)
        {
            System.out.println("不是数字字符");
        }else{
            System.out.println("是数字字符");
        }
//判断这个字符是不是字母
    char ch='a';
    System.out.println(Character.isAlphabetic(ch));
 2)字节与字符串

1)public String(byte[] bytes[]):将字节数转化成字符串

2)public String(byte[],int offset,int length)将字节数组中的内容转化成字符串

3)public byte[] getBytes();将字符串以数组的方式来进行返回

4)public byte[] getBytes(String charsetName) throws UnsupportedException 编码转换处理

byte[] 是把String按照一个字节一个字节的来进行处理,这种情况下适合在网络情况下进行传输,数据存储的场景下进行使用,更适合用于二进制数据来进行操作

char[]是把String按照一个字符一个字符的来进行处理,更适合针对文本数据来进行操作,尤其是包含中文

 //1字节数组转化成字符串
  byte[] arr1={12,34,5,6,7};
  String str=new String(arr1)
//2字符串转化成字节数组
 String str1="abcdefgh";
  byte[] arr=str1.getBytes();
3)字符串的其他方法

1)比较内容:equals()方法,是一种真假类型的比较,在Object的equals默认是比较的是地址

1.2)调用equals方法的时候,先看看两个对象的地址是否相同,是否指向同一个对象,相同返回true,也就是说判断他们是否指向同一个对象

1.3)在进行判断这两个对象的类型是否是相同的(防止你写了一个字符串引用和数组的引用来进行比较),instance of是判断是否是同一种类型,就是进行判断anObject是否是String类型的对象

1.4)如果说它们的类型相同,把形参的Object类型转化成字符串类型(将他进行向下转型转化成String类型的对象),再次比较它们的长度,长度不同,直接返回false

1.5)最后再循环进行比较他们对应字符的相同性,如果有一个对应的字符不相同,直接返回false

2)忽略大小写的比较ASCIl码值

String str1="abcdefg";
String str2="ABCDEFG";
System.out.println(str1.equalsIgnoreCase(str2));//打印true

3)还有忽略大小写比较字符串是否相等

String str1="hello";
String str2="Hello";
System.out.println(str1.equals(str2));//false
System.out.println(str1.equalsIgnoreCase(str2));//true

4)比较字符串的长度:实现comparable接口,重写compareTo方法

1)如果第一个字符和参数的第一个字符不等,结束比较,返回第一个字符的ASCII码差值。

2)如果第一个字符和参数的第一个字符相等,则以第二个字符和参数的第二个字符做比较,以此类推,直至不等为止,返回该字符的ASCII码差值。

3)如果两个字符串不一样长,可对应字符又完全一样,则返回两个字符串的长度差值。

String str3="abcdefg";
String str4="abcdef";
//str1>str2返回的是正数;str1==str2返回的是0;str1<str2返回的是负数
System.out.println(str1.compareTo(str2));//String重写CompareTo方法
 public int compareTo(String anotherString) {
        int len1 = value.length;//先进行获取当前this的字符串的大小
        int len2 = anotherString.value.length;//在进行获取到传入的参数的字符串的大小
        int lim = Math.min(len1, len2);//获取长度的最小值
        char v1[] = value;
        char v2[] = anotherString.value;

        int k = 0;
        while (k < lim) {
            char c1 = v1[k];
            char c2 = v2[k];
            if (c1 != c2) {
                return c1 - c2;
            }
            k++;
        }
        return len1 - len2;
    }

1)public boolean contains(CharSequence s),判断一个子字符串是否存在,因为本质上String实现了CharSequence接口,只要实现了这个接口,那么数据类型都可以用CharSequence来进行接收

2)public int indexOf(String str)

从头开始进行查找指定字符串的位置,查到了就返回位置的开始索引,查不到就返回-1;

3)public int indexOf(String str,int fromindex)从指定位置开始查找字符串的位置

4)public int LastindexOf(String str)从后向前查找子字符串位置

5)public int LastindexOf(String str,int index)从指定位置从后向前进行查找,找到第一个字符的从前向后的索引位置

6)public boolean startWith(String prefix)是否已指定字符串开头

7)public boolean ensEith(String prefix)是否已指定字符串进行开头

String str="abcabcdef";
System.out.println(str.indexOf("a"));//从头开始找,遇到第一个就结束--->0
System.out.println(str.indexOf('d', 4));//从指定位置开始向后找System.out.println(str.indexOf("abc"));//从前向后开始进行查找0
System.out.println("==============================");
System.out.println(str.lastIndexOf('c'));5
System.out.println(str.lastIndexOf('b'));4
System.out.println(str.lastIndexOf("abc"));3
 public static void main(String[] args) {
        //运行时的命令行参数,命令行参数会放在args数组里面
        for(int i=0;i<args.length;i++){
            System.out.println(args[i]);
        }
    }
4)字符串的替换:这里面都是默认创建了一个新的String

1)public String replaceAll(String regex,String replacement)替换指定的所有内容

2)public String replaceFirst(String regex,String replacement)替换首个内容

3)public String replace(char ch1,char ch2)将指定字符替换成指定字符,如果ch1=ch2那么直接返回原来的字符串

4)public String replace(String str1,String str2),构成了重载

//1字符串的替换
String str1="ababababababpppphhh";
String ret=str1.replace("ab","123");//这回创建一个新的对象
//替换首个指定字符的字符串
        ret=str1.replaceFirst("ab","123");
        System.out.println(ret);
//2字符串的截取
String str1="Hello";
String ret=str1.substring(1);//从一号位置开始进行截取,截取后面的字符串
System.out.println(ret);//打印出来的值是llo
ret=str1.substring(1,4);[1,4)从一号位置到四号位置进行字符串的截取
//3去掉字符串两边的空格,但是不可以去掉字符串中间的空格
 String str1=" abcdef gh ";
 String ret=str1.trim();
 System.out.println(ret);
//4查找指定的字符串在原字符串的位置
String str1="abcdefg";
int index=str1.indexOf("abc");
int num=str1.indexOf("def");
System.out.println(index);
System.out.println(num);
//5查找目标字符串是否在源字符串之内
String str1="abcdef";
boolean flag=str1.contains("abcdef");
System.out.println(flag);//打印结果是true
5)字符串进行查找
//1从某个位置开始找
 String str1="abcdefghabcdefgh";
 int index=str1.indexOf("def",2);//从2号位置开始查询def所在的位置
 System.out.println(index);//打印结果是3
 //2从后面向前面找     
 index=str1.lastIndexOf("abc");
 System.out.println(index);//打印结果是8
//3判断某个字符串是否以xx开头
String str="abcdef";
boolean flag=str.startsWith("ab");
System.out.println(flag);
//4判断某个字符串是否以指定的偏移量开始
String str="abcdefg";
boolean flag=str.startsWith("abc",0);
System.out.println(flag);
//5判断某个字符串是否以xx结尾
String str1="abcdefg";
boolean flag=str.endswith("abc");
System.out.println(flag);//false;
6)有关于字符串的拆分---返回值是一个字符串数组

1)public String[] split(String regex),将字符串全部进行拆分

2)public String[] split(String regex,int limit),将字符串进行部分拆分,该数组长度就是limit极限,不会进行均匀分割

1)String str1="name=zhangsan&age=19";
String[] arr1=str1.split("&");
for(String[] ret: arr1)
{
     String[] ss= ret.split("=");
     for(String sss:ss)
     {   
          System.out.println(sss);
      }
}
arr1[0]="name=zhangsan";
arr1[1]="age=19";
2)String str1="abc de f";
String arr1[]=str1.split(" ",2);
for(String ret:arr1)
{
    System.out.println(ret);
}
如果split()后面加上了一个参数2,那么此时返回的字符串就会分成两组
一组是abc,一组是de f;
如果不加上2这个参数或者说压根就没有参数,
此时就会默认分成三组,一组是abc,一组是de,一组是f;
3)String str1="127.0.0.1";
String[] strings=str1.split("\\.");
.号这个字符编译器是无法认清的,所以我们要通过/来进行转义,但是我们还需要对\来进行转义,所以要再加上一个\
for(String hh:strings)
{
    System.out.println(hh);
}
    }
}

注意事项:

1)字符"|","*","+","",前面加上"\\"

String str1="127*0*0*1";
String[] strings=str1.split("\\*",7);
.号这个字符编译器是无法认清的,所以我们要通过/来进行转义,但是我们还需要对/来进行转义,所以要再加上一个/
        for(String hh:strings)
        {
            System.out.println(hh);
        }

    }


2)如果是"",里面就要写上\\

3)如果是一个字符串有多个分隔符,那么我们可以使用|来进行分割

 String str1="java300 12&31#hello";
  String[] strings=str1.split(" |&|#");
  for(String str:strings)
  {
      System.out.println(str);
  }
//这里面的的分隔符有很多,包括空格,&,#我们可以使用|来进行分割

4)分割\\要写四个\\\\

 String str1="1\\2\\3\\4\\5";
 String[] strings=str1.split("\\\\");
 for(String s:strings)
{
   System.out.println(s);
}
 String string="123&8989=90&AAA bbb ccc&BBBB";
 String[] strings=string.split(" |=|&");
 System.out.println(Arrays.toString(strings));
[123, 8989, 90, AAA, bbb, ccc, BBBB]

7)SubString方法:字符串的截取

构成重载,当我们给的参数是0,默认会返回原来的字符串,如果index==0,不会产生新对象,否则就会产生新对象

1)public subString(int),返回值是String(提取子串),从指定位置开始到结尾位置提取子串

 String str1="abcdef";
 String str2=str1.substring(0);
 System.out.println(str2);
//此时str2打印的是abcdef

2)public subString(int,int)返回值是String(提取子串),从指定范围进行截取子串

3)trim()只会进行截取两边的空格,不会进行截取中间的空格,会保留中间的空格

 String str1=" abc bc ";
 String str2=str1.trim();//返回的仍然是new了一个String对象
 System.out.println(str2);

像什么验证码会略大小写比较,在操作输入框的时候自动去除掉空格

4)public String toUpperCase()-----字符串转大写(只针对字母),会把小写字母变成大写

5)public String toLowerCase()-----字符串转小写,只会把大写变成小写

6)public int length()-------求字符串长度

7)public boolean IsEmpty()------字符串是否为空

7)String str1="abcdef";
  String str2=str1.toUpperCase();
//将小写字母全部变成大写字母,同理str1.toLowerCase是把所有的的大写字母变成小写字母
  System.out.println(str2);
8)判断字符串是否为空.isEmpty()方法
String str1="";
System.out.println(str1.isEmpty());----true

1)在这里面我们要注意String str1="";表示这个str1的引用指向一个空字符串,String str2=null,表示str2不会指向任何对象

2)public String intern(),字符串入池操作

concat()方法,出字符串常量池,自动将字符拼接到字符串的末尾
intern()方法,手动入池,表示最后拼接的对象不会进入到常量池里面,会new一个新的对象
 String str1="hello".concat("1");
 String str2="hello1";
 System.out.println(str1==str2);//false

public class DemoKail {
    public static boolean IsAdmin(String array){
        return array.toLowerCase()=="admin";
    }
    public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException {
           System.out.println(IsAdmin("Admin"));
    }
}
打印结果为false,toLowerCase()底层new了一个对象

将一个整数转化成字符串:

1)这里面注意一下咱们的Integer.toString()也是可以把一个整数转化成字符串

2)String.valueOf()是将整数转化成字符串,但是Integer.valueOf()是自动拆箱操作,是将一个包装类型转化成基本数据类型类型,也可以将字符串转化成整数

 String str1=Integer.toString(10);
 String str2=String.valueOf(20);

3)我们也是可以将一个自定义类型的数据转化成字符串:

  public static String valueOf(Object obj) {
        return (obj == null) ? "null" : obj.toString();
    }
class Student{
    public String username;
    public String password;
    public Student(String username, String password) {
        this.username = username;
        this.password = password;
    }
    @Override
    public String toString() {
        return "Student{" +
                "username='" + username + '\'' +
                ", password='" + password + '\'' +
                '}';
    }
}
 Student student=new Student("李佳伟","123456");
 System.out.println(String.valueOf(student));

将字符串转化成整数:

int c=Integer.valueOf("8989");

字符串练习题:

输入:abcqwerabc 输出 abcqwer

输入:aaa输出:a

第一种思路:如果说这个字符在StringBuilder中没有出现过,那么直接进行拼接,如果有出现过,那么不会做任何事情

 public static void main(String[] args) {
        Scanner scanner=new Scanner(System.in);
        while(scanner.hasNextLine()){
            String str=scanner.nextLine();
            ProcessString(str);
        }
    }
    private static void ProcessString(String str) {
        StringBuilder stringBuilder=new StringBuilder();
        for(int i=0;i<str.length();i++){
            char ch=str.charAt(i);
            if(!stringBuilder.toString().contains(ch+"")){//如果说这个字符没有在字符串中出现过
                stringBuilder.append(ch);
            }
        }
        System.out.println(stringBuilder);
    }

第二种思路:通过LinkedHashSet来进行存储元素

 LinkedHashSet<Character> set=new LinkedHashSet<>();
        for(int i=0;i<str.length();i++){
            char ch=str.charAt(i);
            set.add(ch);
        }
        System.out.println(set.toString());
    }

第三种思路:通过标记位的方式来进行去重

我们可以自己new一个boolean数组,因为boolean类型的默认值是false

1)如果说这个字符在数组中没有出现过,那么在数组中默认值就是就是false,咱们就手动进行拼接,并将它的标志位改成true

2)比如说下一次在去访问这个数组的下标的元素的时候,发现标志位已经发生了修改,那么默认不会进行字符串的拼接:

 public static void Process(String string){
        StringBuilder stringBuilder=new StringBuilder();
        boolean[] booleans=new boolean[255];
        for(int i=0;i<string.length();i++){
            char ch=string.charAt(i);
            if(booleans[ch]==false) {
                stringBuilder.append(ch);
                booleans[ch] = true;
            }
        }
        System.out.println(stringBuilder);
    }

练习题2:给出两个有序的整数数组A和B,请将数组B合并到数组A中,变成一个有序的数组

输入用例:[4,5,6],[1,2,3]]--->最后的结果是1,2,3,4,5,6

我们保证A数组有足够的空间存放B数组的元素,A中和B中初始的元素数目分别是m和n,但是A的数组空间是m+n

1)我们最终希望的是把B数组的元素放到A数组里面,最终A数组是一个有序的数组,在这里面我们是不允许开辟额外的空间大小的

2)我们跳出第一个循环之后,有可能i走完了,也有可能j走完了,咱们就可以把剩下的数据拷贝到arra1[index]位置,然后index--就可以了;

我们在这里定义三个指针,k只想最后一个大数组的最后一个位置,我们进行比较arr1[i]和arr2[j]的大小,把较大的值放在下标位k的位置

package com.example.demo;

import java.util.Arrays;
import java.util.LinkedHashSet;
import java.util.Scanner;

public class Solution{
   //m表示数组1中有效数据的个数,n表示数组2中有效数据元素的个数
   public static int[] merge(int[] arr1, int m, int[] arr2, int n){
      int index=m+n-1;
      int i=m-1;
      int j=n-1;
      while(i>=0&&j>=0){
         if(arr1[i]>arr2[j]){
            arr1[index]=arr1[i];
            index--;
            i--;
         }else{
            arr1[index]=arr2[j];
            index--;
            j--;
         }
      }
     while(j>=0){
         arr1[index]=arr2[j];
         j--;
      }
     while(i>=0){
         arr1[index]=arr1[i];
         i--;
         index--;
     }
      return arr1;
   }

   public static void main(String[] args) {
      int[] arr1=new int[7];
      arr1[0]=11;
      arr1[1]=12;
      arr1[2]=90;
      int[] arr2=new int[4];
      arr2[0]=10;
      arr2[1]=17;
      arr2[2]=20;
      arr2[3]=23;
     int[] array= merge(arr1,3,arr2,4);
      System.out.println(Arrays.toString(arr1));
   }

}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值