Java的基础知识回顾之字符串

一、引言

  很多人喜欢在前面加入赘述,事实上去技术网站找相关的内容的一般都应当已经对相应知识有一定了解,因此我不再过多赘述字符串到底是什么东西,在官网中已经写得很明确了,字符串实际上是一种特殊的类,内置了一个字符数组(所以你能对它进行下标查找,包括集合的arraylist底层也是一个数组),并附加了很多其他方法,方便我们进行一些操作。有兴趣的话可以去百度中查阅相关内容。我事先说好了,本文只是我用来回忆和复习的一个粗略笔记,以及一些实验代码。如果需要学习Java,建议去慕课网或者云课堂。

二、关于string类型的一些常识

  Java的类基本上都继承于Object类,也就是都继承了其中的tostring方法,来标识其指向的地址,这是因为Java对象名称实际上只是一个引用,真正的东西还在堆中。Java的理念来源于C艹,但是字符串的运算符实际上不是重载而是在jvm中动了手脚,Java中任何运算符都不能重载!要细究这个问题就要探究JVM,我对Java虚拟机也是一知半解,所以就不猪鼻子插葱了。

1.1Java的相关入门基础

 package TheUnity5;
//java中的字符串连接通过运算符加号完成,他方便了在字符串换行时候的连接
public class Demo1 {
public static void main(String[] args){
String str="the java like skr rap";
String str2="the java like "
+ "skr2 rap";//java编译器不允许一个字符串跨越两行
System.out.println(str);
System.out.println(str2);//一个显示效果 System.out.println("--------------------"); Boolean str3=Boolean.valueOf(false);
System.out.println(""+str3);//string连接数据类型 Object str4=new Object();
System.out.println(str4.toString());
//通过对照说明了封装类其实内部已经对tostring进行了重写
}
}

而事实上很多类的tostring也进行了重写,格式化输出的实际上是类的tostring方法

三、字符串的检索方法

  Java内置了字符串的检索方法indexof,这个方法经过了重载,允许字符和字符串作为参数,且能够指定检索的起始位置,需要注意的是他会返回取到的第一个匹配值然后结束如果你需要检索所有内容你需要进行一个循环判断,而这个方法当你检索的位置超出时,会产生负值。因此在循环判断的过程中,需要注意很多因素。当然你也可以一个一个用charAt去截取然后再去判断,事实上从算法的时间复杂度来说,这两个家伙都是遍历,坏的很。

1.2Java检索指定字符串的出现位置

 package TheUnity5;
//这里总结字符串的相关检索方法
public class Demo2 {
public static void main(String[] args){
String str="do you like van♂ 游戏?";
System.out.println(str);
System.out.println("------------------");
System.out.println("length:"+str.length());
System.out.println(str.indexOf('o'));//这里返回的是第一个O的位置。
System.out.println(str.indexOf('o',str.length()-1));//这里返回从2开始的第一个o的位置,包括2也在检索范围内 //如果想要获得所有的指定字符的位置,只能通过循环的方式
talk1(str,'o');
talk2(str,'o');
}
//通过对每一个字符进行匹配确定位置
public static void talk1(String str,char ch){
int size=str.length();
for(int i=0;i<size-1;i++){
char a=str.charAt(i);
if(a==ch){
System.out.print(i+" ");
}
}
System.out.println("talk1结束");
}
//实际上indexof底层也是遍历匹配,但是对安全性做了很多措施
public static void talk2(String str,char ch){
int i=0;
do{
i=str.indexOf(ch,i);
if(i==str.lastIndexOf(ch)){
System.out.print(i+" ");
break;
}
if(i>=0){
System.out.print(i+" ");
i++;//注意这个位置
}
}while(i>=0);
System.out.println("talk2结束");
}
}

四、Java的字符串修改操作

  Java实际上是开发者因为感受写一个机顶盒c++程序非常烦躁下,开发出的一款语言。非常随意,就和它的名字来源于当时喝的咖啡(其实本来是另外一种咖啡但是名字已经被注册了23333)。因此重复的字符数组裁剪工作被封装成了对应的方法,这就很nice了,常见的操作有字符串的分割,截取,替换,去空格等,下面是相关的代码实现和结果。(懒癌入髓,不过这也能够起到让你们认真看代码的效果【理直气壮.jpg】)

1.3Java的字符串操作

 package TheUnity5;
//Java中内置了一些对字符串的相关操作。方便对字符串进行修改
public class Demo3 {
public static void main(String[] args){
//初始字符串
String str=" deep♂ dark♂ fantasy ";
//字符串截取方法substring会产生一个临时的字符串副本,本质上不会改变原来的字符串
String str1=str.substring(5);
String str2=str.substring(5,11);//不包含第二参数
System.out.println(str);
System.out.println(str1);
System.out.println(str2);
System.out.println("------------------------");
//去除首尾空格,Java的trim方法不会去除字符串内部的非首尾空格
String str3=str.trim();
System.out.println(str3+" "+str.length()+" "+str3.length());
System.out.println("------------------------");
//字符串替换中Java内置了replace方法,但不建议使用因为他会将原字符串所以相同部分全部替换
String str4=str.replace('♂', ' ');
System.out.println(str);
System.out.println(str4);
String str5=change(str,"♂"," ",0,str.length());
String str6=change(str,"♂"," ",str.indexOf("♂")+1,str.length());
System.out.println(str5);
System.out.println(str6);
System.out.println("------------------------");
//java同时也内置了一些字符串开头和结尾的验证,但事实上你会发现大部分字符串的操作方法你都可以自己去重新定义
System.out.println(str.startsWith("deep"));
System.out.println(str.startsWith("deep",1));
System.out.println(str.endsWith("fantasy"));
System.out.println(str.endsWith("fantasy "));
//从输出结果来看,空格也被包含进去了
System.out.println("------------------------");
//Java也有字符串的大小写转换,可以参考我们自定义的替换方法思考他是怎么做到的。
String str7=str.toUpperCase();
String str8=str.toLowerCase();
System.out.println(str7);
System.out.println(str8);
System.out.println(str7.compareTo(str8));//顺带提一下,有兴趣可以自己百度
System.out.println("------------------------");
//字符串分割
String[] sp=str.split("♂");
talk(sp);
sp=str.split("♂", 2);//后面表示分割为几份
talk(sp);
sp=str.split(" ");
talk(sp);//这样能去除所有空格,注意第一个位置为空字符串而不是空。
System.out.println("------------------------");
}
//自定义字符串替换
public static String change(String str,String demo,String demo2,int startindex,int endindex){
String s1=str.substring(0, startindex);
String s2=str.substring(startindex, endindex);
String s3=str.substring(endindex);
s2=s2.replace(demo, demo2);
String s=s1+s2+s3;
return s;
} public static void talk(Object[] objs){
for(int i=0;i<objs.length;i++){
System.out.print("["+objs[i]+"] ");
}
System.out.println();
}
}

五、字符串的内存问题

  如果你在高并发的环境下和我们的demo中一样写,那么恭喜你,你明天可以去人事部结一下工资了。事实上原始的string不光效率不高,而且上述方法都会产生一段字符串对象,Java中string非常特殊,如果你直接赋值给一个引用一段字符串,那么它会先去常量区寻找,如果找不到那么就会将该字符串注入常量池,下次再引用的时候就会直接指向常量池中的内容。而如果是通过new出一段字符串对象,那么它会将你放进推中,并且不会去理你,除非我对这段对象进行操作。

1.4Java字符串内存位置

 package TheUnity5;
//Java字符串的内存问题
public class Demo4 {
public static void main(String[] args){
//对于String,如果你对Java底层的代码有过了解会知道,其实是一个封装的char数组
//而且,是被final修饰的,所以只能赋值一次,String的内容实际是在常量池中的
String str="神奇的沙德沃克先生";
String s1="神奇的沙德沃克先生";
System.out.println(str==s1);
//输出true,说明str与s1指向了同一内存地址
//如果不创建新的字符串对象,相同内容的赋值实际上是多个引用指定一个内存【证明常量池的存在】
System.out.println("------------------------");
String s2=new String("神奇的沙德沃克先生");
System.out.println(s2==str);
System.out.println(s2.equals(str));
//打印结果很明显是内容相同内存不同,这里string对象存在堆中
System.out.println("------------------------");
String s3="神奇的沙德沃克先生";
System.out.println(str==s3);
System.out.println(s2==s3);
//仍然指向最早定义的字符串常量
}
}

1.5对比试验

 package TheUnity5;

 public class Demo5 {
public static void main(String[] args){
//这里接demo4继续讨论
String str=new String("ABC");
String s1="ABC";
System.out.println(s1==str);
//输出结果为false,证明new 一个string对象实际上避免了在常量池注入常量
//而事实上String的大部分方法都会返回一个新的string对象,在程序开发中确实确保了安全性
//但事实上我们需要的不是堆中内存分配的过渡浪费。
}
}

  重点来了,你可能也听说过jvm的对象销毁机制,它是由虚拟机自己决定什么时候销毁的,这就会导致堆中对象不断累加,常规开发环境没什么问题,但是如果是高并发开发那么就会产生很大的内存开销,这是不明智的。Java的开发者也想到了这个问题,所以提出了stringbuffer,提供线程安全的string增强类。在后续开发中在非并发中又开发了stringbuild类,当然后者是线程不安全的,但是性能更高。对这两种增强类的操作不会产生新的对象,因此节省了堆的开销。

1.6两种增强类

 package TheUnity5;
//这里开始正式讲string的两种拓展,他们都是在原对象上进行修改,达到节省空间的效果
public class Demo6 {
public static void main(String[] args){
//Stringbuild
System.out.println("---------------------");
StringBuilder sb=new StringBuilder("NMSL");
StringBuilder sb1=new StringBuilder(" CNM");
sb.append(sb1);//在后部添加
System.out.println(sb.toString());
sb.insert(0, "脏鱼 ");//指定位置插入
System.out.println(sb.toString());
sb.delete(0, 3);
System.out.println(sb.toString());
System.out.println("---------------------");
StringBuffer sf=new StringBuffer("NMSL");
sf.append(" CNM");
//stringbuffer同上,而且更安全。
System.out.println(sf.toString());
//事实上是先有的StringBuffer,然后有的StringBuild,在多线程中前者安全后者不
//在单线程中后者比前者性能更好
}
}

六、正则表达式

  正则表达式实际上是一种规范,在不同的语言会有些许不同,而Java中采用类对其进行处理,具体的语法可以参考各个技术论坛。PS:我是真的烦背书T_T,如果开发要用到这个,我可能得去翻相关的文档,实在记不住。

1.7Java正则表达式的两种用法

 package TheUnity5;

 import java.util.regex.Matcher;
import java.util.regex.Pattern;//Java正则表达式包 //严格意义来说正则表达式并不是一种语言,而是一种规范,不同语言在部分地方有细微查异
//本文只对Java的正则表达式讨论
public class Demo7 {
public static void main(String[] args){
String content="风见啸大胜利!";
String par=".*胜利.*";
boolean isMatch = Pattern.matches(par,content);
System.out.println(isMatch);
System.out.println("--------------------");
String content2="15270003639";
String par2="1[358]\\d{9}";
boolean isMatch2=content2.matches(par2);
System.out.println(isMatch2);
//以上是正则表达式的两种写法,更多的内容推荐从菜鸟教程这些网站中学习
}
}

总结

  漏洞百出,懒惰至极,建议当场出柜【划掉】。

Java基础知识回顾(一):字符串小结的更多相关文章

  1. java基础知识回顾之---java String final类普通方法

    辞职了,最近一段时间在找工作,把在大二的时候学习java基础知识回顾下,拿出来跟大家分享,如果有问题,欢迎大家的指正. /*     * 按照面向对象的思想对字符串进行功能分类.     *      ...

  2. Java基础知识回顾之七 ----- 总结篇

    前言 在之前Java基础知识回顾中,我们回顾了基础数据类型.修饰符和String.三大特性.集合.多线程和IO.本篇文章则对之前学过的知识进行总结.除了简单的复习之外,还会增加一些相应的理解. 基础数 ...

  3. Java基础知识回顾之一 ----- 基本数据类型

    前言 在开始工作至今,学习各种各样的技术之中发现自己的很多Java的基础知识都忘了⊙﹏⊙b汗... 而且越是学习越是发现Java基础的重要性,所以准备单独抽一下时间进行Java基础的重新学习.在重新学 ...

  4. java基础知识回顾之---java String final类普通方法的应用之“按照字节截取字符串”

    /*需求:在java中,字符串“abcd”与字符串“ab你好”的长度是一样,都是四个字符.但对应的字节数不同,一个汉字占两个字节.定义一个方法,按照最大的字节数来取子串.如:对于“ab你好”,如果取三 ...

  5. java基础知识回顾之---java String final类普通方法的应用之“模拟字符串Trim方法”

    /* * 4,模拟一个trim功能一致的方法.去除字符串两端的空白  * 思路: * 1,定义两个变量. * 一个变量作为从头开始判断字符串空格的角标.不断++. * 一个变量作为从尾开始判断字符串空 ...

  6. java基础知识回顾之---java String final类普通方法的应用之“两个字符串中最大相同的子串”

    /* * 3,两个字符串中最大相同的子串. * "qwerabcdtyuiop" * "xcabcdvbn" *  * 思路: * 1,既然取得是最大子串,先看 ...

  7. java基础知识回顾之---java String final类普通方法的应用之字符串数组排序

    /* * 1,给定一个字符串数组.按照字典顺序进行从小到大的排序. * {"nba","abc","cba","zz", ...

  8. Java基础知识回顾

    Java回顾之I/O Java回顾之网络通信 Java回顾之多线程 Java回顾之多线程同步 Java回顾之集合 Java回顾之序列化 Java回顾之反射 Java回顾之一些基础概念 Java回顾之J ...

  9. Java基础知识回顾之二 ----- 修饰符和String

    前言 在上一篇中,回顾了Java的基本数据类型 ,这篇就来回顾下Java中的一些修饰符以及String. 修饰符介绍 Java修饰符主要分为两类: 访问修饰符 非访问修饰符 其中访问修饰符主要包括 p ...

随机推荐

  1. JS常用公共方法封装

    _ooOoo_ o8888888o 88" . "88 (| -_- |) O\ = /O ____/`---'\____ .' \\| |// `. / \\||| : |||/ ...

  2. Asp.net MVC 服务端验证多语言错误

    服务端验证用户提交信息时为了实现多语言使用了资源文件,如: using System.ComponentModel.DataAnnotations; public class UserModel { ...

  3. JavaScript_HTML DEMO_2_事件

    如需在用户点击某个元素时执行代码,请向一个HTML事件属性添加JavaScript代码  OnClick=JavaScriptcript 对事件做出反应 HTML事件属性 使用HTML DOM来分配事 ...

  4. CentOs7 修复 引导启动

    一.修复MBR: MBR(Master Boot Record主引导记录): 硬盘的0柱面.0磁头.1扇区称为主引导扇区.其中446Byte是bootloader,64Byte为Partition t ...

  5. Linux I/O调度

    一) I/O调度程序的总结 1) 当向设备写入数据块或是从设备读出数据块时,请求都被安置在一个队列中等待完成.    2) 每个块设备都有它自己的队列.    3) I/O调度程序负责维护这些队列的顺 ...

  6. hdu-1532 Drainage Ditches---最大流模板题

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1532 题目大意: 给出有向图以及边的最大容量,求从1到n的最大流 思路: 传送门:最大流的增广路算法 ...

  7. c++连接mysql并提示“无法解析的外部符号 _mysql_server_init@12”解决方法&提示缺少“libmysql.dll”

    课程作业要用c++连接mysql server,但是出现些小问题,经查阅资料已经解决,做一下笔记. 环境:vs2017, mysql版本是8.0.16-winx64. 设置项目属性   项目 -  C ...

  8. 2017.12.25 Linux系统的使用

    Linux系统的使用 现在标配的系统是 Linux + Nginx + PHP + MySQL ,这样的配置越来越多的大公司在用的了说到配置不同的是一个公司的规约,比如说挂载一般分为2个盘, / 下面 ...

  9. 第五章 javascript编程可养成的好习惯

    用户点击某个链接时弹出一个新窗口javascript使用window对象的open()方法来创建新的浏览器窗口,这个方法有三个参数:window.open(url,name,features)url: ...

  10. axiospost请求向后端提交数据

    Axios向后端提交数据容易接收不到原因是传参方式是request payload,参数格式是json,而并非用的是form传参,所以在后台用接收form数据的方式接收参数就接收不到了.post表单请 ...