java string 解析_java----String解析

String在内存中的分析:

public class Demo {

public static void main(String[] args){

String a = new String("xx"); //1、首先解释器在堆中的常量池中查找是否有xx变量,没有则创建。有就不在常量池中创建

//2、在堆中再创建一个对象xx;a中的地址指向它;

//所以,new一个字符串。至少会创建一个对象。最多创建两个

String b = "xx"; //直接赋值。最多创建一个对象,如果常量池中有,就不会在创建对象;

//----------------------------------------------------------------

String c = "a";

String e = "a1";

String d = c+1; //在编译的是由,c为变量,并不能确定c的最终只为多少,所以d在运行期才被赋值.会创建新的对象,d指向的是堆中的变量,不会是指向常量池

System.out.println(d==e);//false;

final String f = "a";

String g = f+1; //在编译的时候,由于f为常量,不可以被修改.所以g肯定是确定的,为a1;

String h = "a1";//此时h使用已有的字符串a1;

System.out.println(g==h);//true

String i = getA();

String j = i+1;

String k = "A1";

System.out.println(j==k);//false,getA()方法只能在运行期才能加载。所以i不可知;

final String i2 = getD();

String j2 = i+1;

String k2 = "A1";

System.out.println(j2==k2);//false,getA()方法只能在运行期才能加载。所以i不可知;

}

public static String getA(){

return "A";

}

public static String getD(){

return "A";

}

}

考编译器的优化,编译时"s"+"s"将直接变成"ss",c+c则不会优化,因为不知道在之前的步骤中c会不会发生改变,而针对c+c则是用语法糖,新建一个StringBuilder来处理

String b = "s"+"s";

String c= "s";

System.out.println(a==b); //true

System.out.println(c+c==a);//false

字符串的方法:

占位符

System.out.println(String.format("%s %s","a","b"));

通过索引找字符串:charAt()

String x = "sdfdsfsd";

char a = x.charAt(2);

System.out.println(a);

将字符串变成数组:toCharArray()

String x = "sdfdsfsd";

System.out.println(Arrays.toString(x.toCharArray()));

将字符  数组-->成字符串

//字符数组变成字符串

char[] arr = {'a','b','c'};

System.out.println(new String(arr)); //abc

//字节数据变成字符串

byte[] arr2 = {-73, -88};

System.out.println(new String(arr2)); //法

String s2 = new String(arr,0,2);//不包括2

System.out.println(s2); //ab

字符和数字以及字符和字符串之间转化

char a = '的';

int b = (int)a;

String c = ""+a;

System.out.println(b);

System.out.println(c);

获取每一个字符串的字节:getBytes()

String s = "sdfds";

System.out.println(Arrays.toString(s.getBytes()));//[115, 100, 102, 100, 115]

字符串转编码

String s = "编码";

System.out.println(Arrays.toString(s.getBytes()));

//表示将"编码"编码成gbk

byte[] gbks = s.getBytes("gbk");

System.out.println(Arrays.toString(gbks));

//表示将字节gbks通过编码gbk编码成字符

System.out.println(new String(gbks,"gbk"));

字符在网络中传输绝大多数都采用utf-8编码成字节的。但是在到达tocmat的时候采用ISO-8859-1来解码就会报错。所以我们只要修改解码的方式就可以了

下面这种思想完全错误,解码和编码应该是对字节进行操作。不能对乱码后的字符串进行编码(丝毫没有意义),我们必须从源头的字节入手,原因在于我们对方再用gbk编码,我们采用utf-8解码,所以我们获取到字节的时候,也需要再用gbk解码就好了

String s = "编码";

byte[] gbks = s.getBytes("gbk");

String s1 = new String(gbks, "utf-8");

//将文字故意乱码

System.out.println(s1);//����

//重新对s1进行编码

byte[] bytes = s1.getBytes("utf-8");

//重新对s1进行编码

String s2 = new String(bytes, "gbk");

//String s2 = new String(bytes, "utf-8");

System.out.println(s2);

我们在web应用开发过程中经常遇到输出某种编码的字符,如iso8859-1等,请你讲讲如何输出一个某种编码的字符串?

Public String translate (String str) {

String tempStr = “”;

try {

tempStr = new String(str.getBytes(“ISO-8859-1″), “GBK”);

tempStr = tempStr.trim();

}

catch (Exception e) {

System.err.println(e.getMessage());

}

return tempStr;

}

字符串替代:replace()   replaceAll()

String s = "sdf33d33s";

System.out.println(s.replace("d","w"));

System.out.println(s.replaceAll("\\d", "*")); //使用正则

字符串截取 substring()

String s = "sdf33d33s";

System.out.println(s.substring(2,4));

字符串切割 split()

String s = "sdf33d33s";

System.out.println(Arrays.toString(s.split("d")));

字符串包含字符串contains()

String s = "sdf33d33s";

System.out.println(s.contains("df"));

查找 indexOf()  lastindexOf()

String s = "sdf33d33s";

System.out.println(s.indexOf("df")); //返回字符串所在的索引

判断字符串是否为空 isEmpty()

String s = "sdf33d33s";

System.out.println(s.isEmpty());//为空不代表为null

去掉字符串前后的空格 trim()

String s = "sdf33d33s";

System.out.println(s.trim());

判断字符串是否是指定的字符开头startsWith("x")

boolean s1 = "s".startsWith("s");

字符串反转

System.out.println(new StringBuffer("fs").reverse());

比较大小,忽略大小写 equalsIgnoreCase

"d".equalsIgnoreCase()

StringBuffer使用:

StringBuffer s = new StringBuffer();

s.append(a).append(b).append(1);

s.delete()//删除

s.indexOf()

s.insert()

s.replace()

s.substring()

s.reverse()//字符串反转

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

减少字符串拼接产生多余的垃圾(变量之间的拼接,会产生多余的对象,常量和常量拼接只会产生一个对象)

如果确定的拼接字符串的个数,new StringBuffer(个数) ,加上个数,可以减少数组重复扩展,性能上有提高

补充:StringBuffer和StringBuilder的区别

StringBuffer()    线程安全,性能低,多线程使用;

StringBuilder()  不安全,性能高,单线程使用,使用占大多数

String剖析之拼接

选出字符串中的数字的几种方法;

方法1;

public static void byteArray() {

String s = "sdf34543的GDFSDF";

for (int i = 0; i < s.length(); i++) {

char c = s.charAt(i);

int ai = c; //Integer.valueOf(c)

if (48<=ai&&ai<=57){

System.out.println(c);

}

}

}

方法2;

方法3;

public static void byteArray() {

String s = "sdf3454d的3GDFSDF";

byte[] bytes = s.getBytes();

for (byte b:bytes){

if (b>=48&&b<=58){

char c = (char) b;

System.out.println(c);

}

}

}

StringUtils

isBlank:“   ”:false

isEmpty:“  ” :true

org.apache.commons

commons-lang3

String 中的hashcode()和equals()?

hashcode和equals都是为了对比两个对象是否相等一致,那么为什么会有两个呢?

hashcode()的判断是比较高效的,如果hashcode不一样那么这两个对象一定不相等。但是hashcode相等不能代表这两个对象一定相等,需要equals进行复杂的逻辑判断最终确定是否相等。所有我们在equals判断之前先判断hashcode是否相等可以一定程度提高效率,之后hashcode为了false,就可以不需要在判断equals了。

hashcode目的只是让一个对象只存在唯一的hashcode值,但是一个hashcode值可能会被多个对象共享。所以只要两个对象的hashcode值不相等,那他们对象肯定是不相等的。

这种大量的并且快速的对象对比一般使用的hash容器中,比如hashset,hashmap,hashtable等等,比如hashset里要求对象不能重复,则他内部必然要对添加进去的每个对象进行对比,而他的对比规则就是像上面说的那样,先hashCode(),如果hashCode()相同,再用equal()验证,如果hashCode()都不同,则肯定不同,这样对比的效率就很高了。

我们再来看看String中的hashcode和equals?

String重写了objdect中的hashcode()和equals()方法,所以这两个方法都可以用来判断字符串是否相等。只需要使用任意一个就可以判断?

new Object().equals(objdect)所有的类中默认的equals方法都是和"=="一样的效果,判断内存地址是否一样,只是String重写了equals。

public int hashCode() {

int h = hash;

if (h == 0 && value.length > 0) {

char val[] = value;

for (int i = 0; i < value.length; i++) {

h = 31 * h + val[i];

}

hash = h;

}

return h;

}

public static void main(String[] args) {

StringBuilder stringBuilder = new StringBuilder("11");

System.out.println(stringBuilder.hashCode());

stringBuilder.append("1");

//比较的是内存地址

System.out.println(stringBuilder.hashCode());

String a = "a";

String b = "a";

System.out.println(a.hashCode()+"=="+b.hashCode()

);

equals使用

public class Demo {

public static void main(String[] args){

String a = new String("HH");

String b = new String("HH");

System.out.println(a==b); //false

System.out.println(a.equals(b)); //true //字符串对象重写了equals方法

String c = "hh";

String d = "hh";

System.out.println(c==d); //true

System.out.println(c.equals(d)); //true

Integer a = 127; //Integer相当于引用和int基本数据类型不同

Integer b = 127;

System.out.println(a==b); //true,由于享元模式,java解释器会缓存1个字节中的数,第二次创建127,就直接 从缓存返回数据;

System.out.println(a.equals(b)); //true

Integer c = 128;

Integer d = 128;

System.out.println(c==d); //false,由于128大于一个字节,不缓存,就会每次新new出一个对象.

System.out.println(c.equals(d)); //true

}

}

对象

public class Demo {

public static void main(String[] args){

Student s1 = new Student(1,"hh");

Student s2 = new Student();

System.out.println(s1==s2); //false

System.out.println(s1.equals(s2)); //false

}

}

如果需求是两个对象的传递的值是一样的,那么我们就认为两个对象是相等的,此时需要重写equals方法

public class Demo {

public static void main(String[] args){

Student s1 = new Student(1,"hh");

Student s2 = new Student(1,"hh");

System.out.println(s1.equals(s2)); //true 重写了equals方法

}

}

class Student{

private int id;

private String name;

public Student(){};

public Student(int id,String name){

this.id = id;

this.name = name;

}

public String toString(){ //重写toString(),建议

return "id="+this.id+",name="+this.name;

}

public boolean equals(Object obj){ //使用object接受

if(this == obj){

return true;

}

else{

if(obj instanceof Student){

Student s = (Student)(obj);

if(s.id==this.id&&s.name.equals(this.name)){

return true;

}

}

}

return false;

}

}

StringUtils工具类

String response = StreamUtils.copyToString( conn.getInputStream(), Charset.forName("UTF-8")); //将输入流转成字符串

String 分割字符串

maven

org.assertj

assertj-core

3.18.1

test

com.google.guava

guava

30.0-jre

使用

Iterable a = Splitter.on("|").omitEmptyStrings().trimResults().split("|d||d|||");

ArrayList b = Lists.newArrayList(a);

System.out.print(b.size());

Iterable a1 = Splitter.on("|").trimResults().split("|d||d||||||");

ArrayList b1 = Lists.newArrayList(a1);

System.out.print(b1.size());

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值