• 关于

    字符比较是什么

    的搜索结果

问题

300万数据量的汉字拼音排序,能优化到什么程度呢?:报错

每个字符串通常是汉字字符串,也有可能夹杂少量英文数字字符,长度在0-128个之间 我目前的做法是先将所有汉字生成一个拼音排序队列,长度有2w多个 然后比较的时候直接解码,从队列中获取排列序号,再根据此排列序号按照通常字符串比较的...
kun坤 2020-06-14 14:05:26 0 浏览量 回答数 0

问题

【百问百答】Java开发手册灵魂15问之为什么不建议在for循环中使用“+”进行字符串拼接

1. 什么是String,它是什么数据类型? 2. 创建String对象的不同方式有哪些? 3. 写一个方法来判断一个String是否是回文? 4. 如何让一个字符串变成小写或大...
huc_逆天 2021-01-15 10:47:35 7 浏览量 回答数 0

问题

java如何识别全角字符

如果我有一个比较大的文件,需要判断其中是否有全角字符,如果有,输出该字符并标明所在行。比较好的实现方式有什么呢?比如,怎么读取file,是按行读还是?各位大神求指教,最好贴详细代码...
蛮大人123 2019-12-01 20:24:11 1344 浏览量 回答数 1

问题

jquery字符串比较,字符串比较不了的问题

这段程序运行结果是:证明s1也是“已提交审核”为什么s1==s2没有反应??...
吴孟桥 2019-12-01 19:44:04 983 浏览量 回答数 1

问题

sql字符比较问题

通过vb6将word文本(wordApp.ActiveDocument.Range().text,选择题答案,比如A)导入sql一表中,另一表手工录入学生答案(比如A),将两者字符进行比较判断答案正误并获得相应分值时,出现无法解决的问题:个...
吴孟桥 2019-12-01 19:54:44 958 浏览量 回答数 1

问题

应该返回false的用户输入返回true

到目前为止,我一直在程序中使用运算符比较所有字符串。但是,我遇到了一个错误,将其中一个更改为错误.equals(),并修复了该错误。 true==falseÿ...
养狐狸的猫 2019-12-01 20:00:45 8 浏览量 回答数 0

回答

你为什么要从字符串中得到一个int值,因为它告诉你猜测值太低了?可以将其视为字符串,然后可以将字符串与.equals进行比较,以查看字符串的值是否相同。如果是,你告诉程序它太低或太高。
一码平川MACHEL 2019-12-02 03:01:08 0 浏览量 回答数 0

回答

   为了防止黑客攻击,原理大致是这样:常规的字符串比较方法,会对字符串中的字符从头到尾逐字符进行对比,当出现不同字符时 return false,那么前缀正确字符越多,比较时间就越长,黑客可以通过程序去尝试不同的前缀,得到统计规律,逐步猜测出所有密码值     而 jfinal 提供的 slowEquals 方法,确保了攻击者无论发送什么密码过来,比较时间是一样的,因此这类攻击方法将失效。当然,在实际操作的时候要稍微改进一下,因为大部分密码都是 hash 过的值,而非明文,所以黑客在制做这个最终对比字符串时,会让 hash 过的字符串去对比     jfinal 源代码中的种种考虑是极其深刻的,很少有人注意到这点。######回复 @JFinal : 不过JFinal能提供这样的技术细节还是很赞的######回复 @JFinal : 回复 @JFinal : 文中所述时间攻击的假设有两条: 1. 攻击者知道哈希函数类型, 2. 攻击者知道盐值. 第一条可以从公开的方法中挑选尝试, 第二条一般情况下没有太大的可能性. 尤其是当系统采用bcrypt之类的算法, 每个盐值都随机产生, 而且不用和数据存储在一起. 至于其他的算法, 完全可以随机生成盐值放入数据库. 外界攻击无从获得######回复 @罗格林 : 前面说的 "hash过的" 是指服务端程序去做的 hash 动作,并非指黑客发送 hash 过的字符串######回复 @罗格林 : 一般人无法通过上面的信息量明白原因,网上很多这方面资料,osc也有: http://www.oschina.net/news/49852/salted-password-hash######黑客发送任何字符串都会经过hash运算, 怎么可能发出hash 过的字符串去对比?
kun坤 2020-06-06 13:41:45 0 浏览量 回答数 0

回答

` String a = "ab"; String bb = "b"; String b = "a" + bb; System.out.println((a == b)); //result = false ` 分析:JVM对于字符串引用,由于在字符串的"+"连接中,有字符串引用存在,而引用的值在程序编译期是无法确定的,即"a" + bb无法被编译器优化,只有在程序运行期来动态分配并将连接后的新地址赋给b。所以上面程序的结果也就为false。 `String a = "ab";final String bb = "b";String b = "a" + bb;System.out.println((a == b)); //result = true`分析:和上面例子唯一不同的是bb字符串加了final修饰,对于final修饰的变量,它在编译时被解析为常量值的一个本地拷贝存储到自己的常量 池中或嵌入到它的字节码流中。所以此时的"a" + bb和"a" + "b"效果是一样的。故上面程序的结果为true。 `String a = "ab";final String bb = getBB();String b = "a" + bb;System.out.println((a == b)); //result = falseprivate static String getBB() { return "b"; }`分析:JVM对于字符串引用bb,它的值在编译期无法确定,只有在程序运行期调用方法后,将方法的返回值和"a"来动态连接并分配地址为b,故上面 程序的结果为false。 "=="是比较两个字符串引用的地址是否相同,即是否指向同一个对象,而equals方法则比较字符串的内容是否相同。例如String a = "abc"; String b = "abc";a == b返回true,a.equals(b)同样返回true,这是为什么呢?原来程序在运行时有一个字符串池,创建字符串时会先查找池中是否有相应的字符串,如果已经存在的话只需把引用指向它即可,如果没有则新建一个。上例中创建a时,会在字符串池中首先创建一个"abc",然后a指向它;创建b时,由于"abc"已经存在,b直接指向它即可。若改为:String a = "abc";String b = new String("abc");则a == b返回false,a.equals(b)返回true。因为创建b时不管"abc"是否存在都会new一个新的"abc",从而a和b指向的字符创对象是不同的,因此返回false。
蛮大人123 2019-12-02 01:56:58 0 浏览量 回答数 0

问题

html拼接字符串中特殊字符(‘ “ 等的转义问题)

问题描述:html拼接一段字符串,然后append()上去,比如这么一句代码 var string5 = " test2222";str1可以是其他地方获取过来的一段字符串,而且该段字符串中有引号,如ABC'EFG'XX""问题在于 把这段...
a123456678 2019-12-01 19:29:38 1096 浏览量 回答数 1

问题

关于javascript对象的一个奇怪的问题

各位大神能否解释一下,为何上图的 str 是字符串类型,在控制台打印出str, 再用双灯号去比对的时候,返回是false呢? typeof 的结果是字符串,然而把值复制出来和str比较却又不对,那么str 到底是什么东西?...
小旋风柴进 2019-12-01 20:26:05 796 浏览量 回答数 1

问题

请问rowkey各组成部分,用什么类型比较好?

请问,需要以时间作为rowkey的组成部分,请问用什么类型比较好?比如说时间,用下面哪种形式好: 1)以“YYYYMMDDHHMISS”形式的字符串(例如“20181231123059”)来表示,占14字节---查询结果直观,方便理解 ...
hbase小能手 2019-12-01 20:25:44 496 浏览量 回答数 1

回答

先说说这几个例子的区别吧:1、 include string url = “segmentfault.com”;url是一个string对象。为了更加容易地操纵字符串,cpp为我们定义了一个string类(string并不是cpp的关键字),你可以通过它来定义字符串对象,然后通过调用它的方法来获取该字符串的信息,例如获取它的长度:url.length()又或者对它进行操纵,例如拼接: string scheme = “http://”cout << scheme+url << endl; //输出http://segmentfault2、下面的三种写法都可以看作是一种: const char* url = “segmentfault”;因为 const char url[](字符数组),数组名url在编译时会被隐式转为为指针char,指向字符串的首个字符's'。至于号的位置,有人喜欢把它放到靠近类型,有人喜欢把它放到靠近变量名,这里有一个关于这个问题讨论的topic http://topic.csdn.net/u/20101117/10/f... 又因为是常量字符串,所以你不能对它进行修改 url[0]='x';//错误,不可以进行修改,就算没有用const来修饰,也不可以但是在string中却可以 string url = “segmentfault.com”;url[0] = 'x';//OK这是因为string为我们承担了管理内存的任务。如果你想要对它进行拼接,你需要自己写一个函数,又或者调用cstring库中的strcat或strncat函数。 在c/cpp中,有两种作用,一种是用来定义指针类型,char 就是字符指针。另外一种就是取值,取指针指向的值,想上面所说的 const char *url = “segmentfault”;url是指向字符串的首个字符,所以你对指针url取值,得到的就是字符's' cout << *url << endl;//输出's'所以,总的来说,string用起来会比较方便,常量字符串在操纵起来就有点麻烦,也可以说是灵活吧,什么时候用哪个,就需要你自己衡量了。至于性能上,我想我还没有能力来分析!
a123456678 2019-12-02 02:02:22 0 浏览量 回答数 0

问题

c++中使用equal 比较两个C风格字符串vector的问题

c++primer(第5版)中的一个练习题 P339 T10.5如果两个容器中保存的是c风格字符串 list,运用equal 比较两个容器会出现什么样的结果? #include <list> #include <iostr...
a123456678 2019-12-01 20:11:24 1433 浏览量 回答数 4

问题

有什么数据库对集合和JSON类型的数据支持是比较好的呢?

现在项目中使用的是MySQL数据库,使用得越多越发现MySQL数据库的功能太弱了。。。所以在这里求教一下:比如:在一个文章表里有个列KEYWORDIDS,存储了关键词的id,用空格或是其它字符隔开,并设置了全文检索,查询的时候很方便。不过到...
a123456678 2019-12-01 20:13:19 2689 浏览量 回答数 1

问题

在asp中比较记录集字段与字符串时的问题

' rs 是记录集 If rs("num")="1" Then Response.Write "1" End If If rs("num")=Server.HTMLEncode("1") Then Response.Write "2...
小旋风柴进 2019-12-01 19:47:16 959 浏览量 回答数 1

回答

去和网上的方法比较,如果你的结果不对,说明你的程序有错,不要问为什么。###### 引用来自“jorneyr”的答案 去和网上的方法比较,如果你的结果不对,说明你的程序有错,不要问为什么。 因为main方法执行的密文在网上是正确的。 ######建议换个md5加密方法调用试试,比如Apache的加密###### 其实你两个结果都是对的,只不过一个是把字符串UTF8编码后的结果,  ###### 引用来自“figer1”的答案 其实你两个结果都是对的,只不过一个是把字符串UTF8编码后的结果,  因为中文已经不能转码了,可否把中文字符转byte数组类型,然后再转UTF-8就达到效果了? ###### 兄弟,你这个问题怎么解决的呀,我今天也见鬼了。 ######需要制定为“utf-8”编码。md.update( x.getBytes(“utf-8”) );
爱吃鱼的程序员 2020-06-03 17:10:20 0 浏览量 回答数 0

问题

app token 怎么生成

1 app token现在用的地方比较多,请问一般采用什么方式生成,是比如:时间戳+userid+随机字符串。一般规律是什么?...
河南 2019-12-01 19:51:19 2369 浏览量 回答数 1

问题

{ "a":"1","b":"2"} 怎么能快速变成 "a:1;b:2",效率高点?

rt:我现在是比较笨的方法,把单个json循环单个拼接;如果json数据大的话,效率会比较低吧!然后又想着用JSON.stringify变成字符串后,在正则去掉{}什么的;不知道还有其他方法吗?字符串替换 逗号替换为分号,双引号替换为空,大...
爵霸 2019-12-01 20:04:13 1053 浏览量 回答数 2

问题

html拼接字符串中特殊字符(‘ “ 等的转义问题)

问题描述:html拼接一段字符串,然后append()上去,比如这么一句代码 var string5 = "&lt;div class='div2' name='"+str1+"'&gt;test2222&lt;/div&gt;";str1...
云栖技术 2019-12-01 19:26:56 1276 浏览量 回答数 1

问题

hibernate的hql多个查询条件如何快捷的拼接

比如说有个检索,可能要检索A,B,C,D,E五个属性,那么在hql中拼接的语句就应该是from table where A=? and b=? and C=? and D=? and E=?这样子,但是现实情况是比较复杂的,如果手动去拼接这...
云栖技术 2019-12-01 19:40:12 901 浏览量 回答数 1

问题

请教一下各位大神,http中get请求里面携带的password一般采用怎样的方式生成?

我最近在测试一个别人写的APP,APP用户经常投诉说APP报告“密码错误”,但实际输入的密码是正确的,我发现该APP的密码是客户端通过HTTP的get请求送给服务器的,get里面的passsword字段是32位的加密(或者hash)后的字符...
杨冬芳 2019-12-01 20:09:43 852 浏览量 回答数 1

回答

字符串,是Java中最常用的一个数据类型了。 本文,也是对于Java中字符串相关知识的一个补充,主要来介绍一下字符串拼接相关的知识。本文基于jdk1.8.0_181。 字符串拼接 字符串拼接是我们在Java代码中比较经常要做的事情,就是把多个字符串拼接到一起。 我们都知道,String是Java中一个不可变的类,所以他一旦被实例化就无法被修改。 不可变类的实例一旦创建,其成员变量的值就不能被修改。这样设计有很多好处,比如可以缓存hashcode、使用更加便利以及更加安全等。 但是,既然字符串是不可变的,那么字符串拼接又是怎么回事呢? 字符串不变性与字符串拼接 其实,所有的所谓字符串拼接,都是重新生成了一个新的字符串。下面一段字符串拼接代码: String s = "abcd"; s = s.concat("ef"); 其实最后我们得到的s已经是一个新的字符串了。如下图  s中保存的是一个重新创建出来的String对象的引用。 那么,在Java中,到底如何进行字符串拼接呢?字符串拼接有很多种方式,这里简单介绍几种比较常用的。 使用+拼接字符串 在Java中,拼接字符串最简单的方式就是直接使用符号+来拼接。如: String wechat = "Hollis"; String introduce = "每日更新Java相关技术文章"; String hollis = wechat + "," + introduce; 这里要特别说明一点,有人把Java中使用+拼接字符串的功能理解为运算符重载。其实并不是,Java是不支持运算符重载的。这其实只是Java提供的一个语法糖。后面再详细介绍。 运算符重载:在计算机程序设计中,运算符重载(英语:operator overloading)是多态的一种。运算符重载,就是对已有的运算符重新进行定义,赋予其另一种功能,以适应不同的数据类型。 语法糖:语法糖(Syntactic sugar),也译为糖衣语法,是由英国计算机科学家彼得·兰丁发明的一个术语,指计算机语言中添加的某种语法,这种语法对语言的功能没有影响,但是更方便程序员使用。语法糖让程序更加简洁,有更高的可读性。 concat 除了使用+拼接字符串之外,还可以使用String类中的方法concat方法来拼接字符串。如: String wechat = "Hollis"; String introduce = "每日更新Java相关技术文章"; String hollis = wechat.concat(",").concat(introduce); StringBuffer 关于字符串,Java中除了定义了一个可以用来定义字符串常量的String类以外,还提供了可以用来定义字符串变量的StringBuffer类,它的对象是可以扩充和修改的。 使用StringBuffer可以方便的对字符串进行拼接。如: StringBuffer wechat = new StringBuffer("Hollis"); String introduce = "每日更新Java相关技术文章"; StringBuffer hollis = wechat.append(",").append(introduce); StringBuilder 除了StringBuffer以外,还有一个类StringBuilder也可以使用,其用法和StringBuffer类似。如: StringBuilder wechat = new StringBuilder("Hollis"); String introduce = "每日更新Java相关技术文章"; StringBuilder hollis = wechat.append(",").append(introduce); StringUtils.join 除了JDK中内置的字符串拼接方法,还可以使用一些开源类库中提供的字符串拼接方法名,如apache.commons中提供的StringUtils类,其中的join方法可以拼接字符串。 String wechat = "Hollis"; String introduce = "每日更新Java相关技术文章"; System.out.println(StringUtils.join(wechat, ",", introduce)); 这里简单说一下,StringUtils中提供的join方法,最主要的功能是:将数组或集合以某拼接符拼接到一起形成新的字符串,如: String []list ={"Hollis","每日更新Java相关技术文章"}; String result= StringUtils.join(list,","); System.out.println(result); //结果:Hollis,每日更新Java相关技术文章 并且,Java8中的String类中也提供了一个静态的join方法,用法和StringUtils.join类似。 以上就是比较常用的五种在Java种拼接字符串的方式,那么到底哪种更好用呢?为什么阿里巴巴Java开发手册中不建议在循环体中使用+进行字符串拼接呢?  (阿里巴巴Java开发手册中关于字符串拼接的规约) 使用+拼接字符串的实现原理 前面提到过,使用+拼接字符串,其实只是Java提供的一个语法糖, 那么,我们就来解一解这个语法糖,看看他的内部原理到底是如何实现的。 还是这样一段代码。我们把他生成的字节码进行反编译,看看结果。 String wechat = "Hollis"; String introduce = "每日更新Java相关技术文章"; String hollis = wechat + "," + introduce; 反编译后的内容如下,反编译工具为jad。 String wechat = "Hollis"; String introduce = "\u6BCF\u65E5\u66F4\u65B0Java\u76F8\u5173\u6280\u672F\u6587\u7AE0";//每日更新Java相关技术文章 String hollis = (new StringBuilder()).append(wechat).append(",").append(introduce).toString(); 通过查看反编译以后的代码,我们可以发现,原来字符串常量在拼接过程中,是将String转成了StringBuilder后,使用其append方法进行处理的。 那么也就是说,Java中的+对字符串的拼接,其实现原理是使用StringBuilder.append。 concat是如何实现的 我们再来看一下concat方法的源代码,看一下这个方法又是如何实现的。 public String concat(String str) { int otherLen = str.length(); if (otherLen == 0) { return this; } int len = value.length; char buf[] = Arrays.copyOf(value, len + otherLen); str.getChars(buf, len); return new String(buf, true); } 这段代码首先创建了一个字符数组,长度是已有字符串和待拼接字符串的长度之和,再把两个字符串的值复制到新的字符数组中,并使用这个字符数组创建一个新的String对象并返回。 通过源码我们也可以看到,经过concat方法,其实是new了一个新的String,这也就呼应到前面我们说的字符串的不变性问题上了。 StringBuffer和StringBuilder 接下来我们看看StringBuffer和StringBuilder的实现原理。 和String类类似,StringBuilder类也封装了一个字符数组,定义如下: char[] value; 与String不同的是,它并不是final的,所以他是可以修改的。另外,与String不同,字符数组中不一定所有位置都已经被使用,它有一个实例变量,表示数组中已经使用的字符个数,定义如下: int count; 其append源码如下: public StringBuilder append(String str) { super.append(str); return this; } 该类继承了AbstractStringBuilder类,看下其append方法: public AbstractStringBuilder append(String str) { if (str == null) return appendNull(); int len = str.length(); ensureCapacityInternal(count + len); str.getChars(0, len, value, count); count += len; return this; } append会直接拷贝字符到内部的字符数组中,如果字符数组长度不够,会进行扩展。 StringBuffer和StringBuilder类似,最大的区别就是StringBuffer是线程安全的,看一下StringBuffer的append方法。 public synchronized StringBuffer append(String str) { toStringCache = null; super.append(str); return this; } 该方法使用synchronized进行声明,说明是一个线程安全的方法。而StringBuilder则不是线程安全的。 StringUtils.join是如何实现的 通过查看StringUtils.join的源代码,我们可以发现,其实他也是通过StringBuilder来实现的。 public static String join(final Object[] array, String separator, final int startIndex, final int endIndex) { if (array == null) { return null; } if (separator == null) { separator = EMPTY; } // endIndex - startIndex > 0: Len = NofStrings *(len(firstString) + len(separator)) // (Assuming that all Strings are roughly equally long) final int noOfItems = endIndex - startIndex; if (noOfItems <= 0) { return EMPTY; } final StringBuilder buf = new StringBuilder(noOfItems * 16); for (int i = startIndex; i < endIndex; i++) { if (i > startIndex) { buf.append(separator); } if (array[i] != null) { buf.append(array[i]); } } return buf.toString(); } 效率比较 既然有这么多种字符串拼接的方法,那么到底哪一种效率最高呢?我们来简单对比一下。 long t1 = System.currentTimeMillis(); //这里是初始字符串定义 for (int i = 0; i < 50000; i++) { //这里是字符串拼接代码 } long t2 = System.currentTimeMillis(); System.out.println("cost:" + (t2 - t1)); 我们使用形如以上形式的代码,分别测试下五种字符串拼接代码的运行时间。得到结果如下: + cost:5119 StringBuilder cost:3 StringBuffer cost:4 concat cost:3623 StringUtils.join cost:25726 从结果可以看出,用时从短到长的对比是: StringBuilder<StringBuffer<concat<+<StringUtils.join StringBuffer在StringBuilder的基础上,做了同步处理,所以在耗时上会相对多一些。 StringUtils.join也是使用了StringBuilder,并且其中还是有很多其他操作,所以耗时较长,这个也容易理解。其实StringUtils.join更擅长处理字符串数组或者列表的拼接。 那么问题来了,前面我们分析过,其实使用+拼接字符串的实现原理也是使用的StringBuilder,那为什么结果相差这么多,高达1000多倍呢? 我们再把以下代码反编译下: long t1 = System.currentTimeMillis(); String str = "hollis"; for (int i = 0; i < 50000; i++) { String s = String.valueOf(i); str += s; } long t2 = System.currentTimeMillis(); System.out.println("+ cost:" + (t2 - t1)); 反编译后代码如下: long t1 = System.currentTimeMillis(); String str = "hollis"; for(int i = 0; i < 50000; i++) { String s = String.valueOf(i); str = (new StringBuilder()).append(str).append(s).toString(); } long t2 = System.currentTimeMillis(); System.out.println((new StringBuilder()).append("+ cost:").append(t2 - t1).toString()); 我们可以看到,反编译后的代码,在for循环中,每次都是new了一个StringBuilder,然后再把String转成StringBuilder,再进行append。 而频繁的新建对象当然要耗费很多时间了,不仅仅会耗费时间,频繁的创建对象,还会造成内存资源的浪费。 所以,阿里巴巴Java开发手册建议:循环体内,字符串的连接方式,使用 StringBuilder 的 append 方法进行扩展。而不要使用+。 总结 本文介绍了什么是字符串拼接,虽然字符串是不可变的,但是还是可以通过新建字符串的方式来进行字符串的拼接。 常用的字符串拼接方式有五种,分别是使用+、使用concat、使用StringBuilder、使用StringBuffer以及使用StringUtils.join。 由于字符串拼接过程中会创建新的对象,所以如果要在一个循环体中进行字符串拼接,就要考虑内存问题和效率问题。 因此,经过对比,我们发现,直接使用StringBuilder的方式是效率最高的。因为StringBuilder天生就是设计来定义可变字符串和字符串的变化操作的。 但是,还要强调的是: 1、如果不是在循环体中进行字符串拼接的话,直接使用+就好了。 2、如果在并发场景中进行字符串拼接的话,要使用StringBuffer来代替StringBuilder。
montos 2020-06-01 21:30:32 0 浏览量 回答数 0

问题

时间复杂度 7月1日 【今日算法】

究竟什么是时间复杂度 时间复杂度就是用来方便开发者估算出程序的运行时间 我们该如何估计程序运行时间呢,我们通常会估计算法的操作单元数量,来代表程序消耗的时间, 这里我们默认CPU的每个单元运行消...
游客ih62co2qqq5ww 2020-07-02 23:54:51 6 浏览量 回答数 1

问题

JAVA 日期格式问题

yyyy-mm-ddThr:mi:se这个时间格式,出来的 2015-06-08T09:48:12 这样子的。然后存进去数据库是字符串的格式,这串 2015-06-08T09:48:12 字符怎么判断时间先后啊,就是比较大小,以...
小旋风柴进 2019-12-01 20:15:37 1020 浏览量 回答数 1

回答

排序的数据类型不局限于整数,只要是定义了小于运算的类型都可以,比如字符串类string。如果是没有定义小于运算的数据类型,或者想改变排序的顺序,就要用到第三参数——比较(compare)函数。比较函数是一个自己定义的函数,返回值是bool型,它规定了什么样的关系才是“小于”。比较时sort函数根据comp函数进行判断输的大小,系统默认ab时返回为真,那么最终得到的排序结果也相应的从小到大变成从大到小。
a123456678 2019-12-02 02:01:37 0 浏览量 回答数 0

回答

String是Java中一个比较基础的类,每一个开发人员都会经常接触到。而且,String也是面试中经常会考的知识点。String有很多方法,有些方法比较常用,有些方法不太常用。今天要介绍的subString就是一个比较常用的方法,而且围绕subString也有很多面试题。 substring(int beginIndex, int endIndex)方法在不同版本的JDK中的实现是不同的。了解他们的区别可以帮助你更好的使用他。为简单起见,后文中用substring()代表substring(int beginIndex, int endIndex)方法。 substring() 的作用 substring(int beginIndex, int endIndex)方法截取字符串并返回其[beginIndex,endIndex-1]范围内的内容。 String x = "abcdef"; x = x.substring(1,3); System.out.println(x); 输出内容: bc 调用substring()时发生了什么? 你可能知道,因为x是不可变的,当使用x.substring(1,3)对x赋值的时候,它会指向一个全新的字符串: 然而,这个图不是完全正确的表示堆中发生的事情。因为在jdk6 和 jdk7中调用substring时发生的事情并不一样。 JDK 6中的substring String是通过字符数组实现的。在jdk 6 中,String类包含三个成员变量:char value[], int offset,int count。他们分别用来存储真正的字符数组,数组的第一个位置索引以及字符串中包含的字符个数。 当调用substring方法的时候,会创建一个新的string对象,但是这个string的值仍然指向堆中的同一个字符数组。这两个对象中只有count和offset 的值是不同的。 下面是证明上说观点的Java源码中的关键代码: //JDK 6 String(int offset, int count, char value[]) { this.value = value; this.offset = offset; this.count = count; } public String substring(int beginIndex, int endIndex) { //check boundary return new String(offset + beginIndex, endIndex - beginIndex, value); } JDK 6中的substring导致的问题 如果你有一个很长很长的字符串,但是当你使用substring进行切割的时候你只需要很短的一段。这可能导致性能问题,因为你需要的只是一小段字符序列,但是你却引用了整个字符串(因为这个非常长的字符数组一直在被引用,所以无法被回收,就可能导致内存泄露)。在JDK 6中,一般用以下方式来解决该问题,原理其实就是生成一个新的字符串并引用他。 x = x.substring(x, y) + "" 关于JDK 6中subString的使用不当会导致内存系列已经被官方记录在Java Bug Database中: 内存泄露:在计算机科学中,内存泄漏指由于疏忽或错误造成程序未能释放已经不再使用的内存。 内存泄漏并非指内存在物理上的消失,而是应用程序分配某段内存后,由于设计错误,导致在释放该段内存之前就失去了对该段内存的控制,从而造成了内存的浪费。 JDK 7 中的substring 上面提到的问题,在jdk 7中得到解决。在jdk 7 中,substring方法会在堆内存中创建一个新的数组。 Java源码中关于这部分的主要代码如下: //JDK 7 public String(char value[], int offset, int count) { //check boundary this.value = Arrays.copyOfRange(value, offset, offset + count); } public String substring(int beginIndex, int endIndex) { //check boundary int subLen = endIndex - beginIndex; return new String(value, beginIndex, subLen); } 以上是JDK 7中的subString方法,其使用new String创建了一个新字符串,避免对老字符串的引用。从而解决了内存泄露问题。 所以,如果你的生产环境中使用的JDK版本小于1.7,当你使用String的subString方法时一定要注意,避免内存泄露。
montos 2020-06-01 21:28:15 0 浏览量 回答数 0

回答

"这不典型的Stack应用吗? 楼主还在犹豫什么呢??######回复 <a href=""http://my.oschina.net/u/147822"" class=""referer"" target=""_blank"">@Grrrr : 不太明白,这种方式能拿到符合要求的 [ ] 中间的字符串信息吗?######回复 <a href=""http://my.oschina.net/jsan"" class=""referer"" target=""_blank"">@JSON : 哎```楼主可以变通下嘛~~把 ' 也看做成对出现的不就可以了,只不过不进行转义.. 也就是Stack里面只存 ' 和 [ ] 这三种符号.######我看下Stack,很多用来判断括号等是否成对出现的,这个我上面的代码也支持,但是如果判断一个 [ 是否出现在 ' ' 单引号中就比较难了。######愿闻其详,我还真没有用过Stack######啊?没有人能帮忙的吗?######不知道你这是要干嘛######我做的一个功能解析器,提取符合语法定义[ ] 中的字符串内容######正则表达式看一下######找 [ ] 配对匹配比较容易,不论是stack实现,还是计数实现都是可以的,但是关键是:要判断 [ ] 是否出现在 单引号 ' ' 中就比较难了。###### stack + deterministic state machine 一种比较简单是实现是“递归下降回溯”法。楼主参考《编译原理实践》(大概是这个名儿)中,词法解析的一个例子 —— 用“递归下降回溯法“编写算术表达式的解析和计算。 大致如下: parse_exp() parse_square_exp() parse_quote_exp() 然后根据目前字符决定函数,互相调用。######错了。是”递归下降分析“,应该没有回溯这一步。###### public static void main(String[] args) { String t1 = " a='\'[ab []' [b=2, c=3]"; String [] t1_arg = t1.split(""); boolean isQuat = false; int bn = -1; int en = 0; int strIndex = 0; for (String s : t1_arg) { if (s.equals("'") || s.equals("\'")) { isQuat = !isQuat; } if(!isQuat && s.equals("[") && bn < 0) { bn = strIndex; } if(!isQuat && s.equals("]") ) { en = strIndex; } strIndex ++; } System.out.println(t1.substring(bn-1)); } 我写了个 就一个循环,试了你当前给的那4个字符,你看看行不行######s.equals("\'") 这个不会成立,因为是转义字符,所以,不会有 \' 出现, \' java 认为是 '###### 语法解析,首先要保证语法是没有歧义的; 这个例子就有些诡异: [ b=2, c=3 [, d=4] ] 如果是 [b=2, c=3, [d=4]] 就比较好 首先需要找到有哪些词法单元(终结符): 标识符 ID 整数 ' 单引号 \ 反斜杠 =赋值符号 [ 左中括号 ] 右中括号   再看有哪些语法单元(非终结符): 转意字符: \+单个字符 字符串: '任意字符或者转意字符' 赋值语句: 标识符 = 表达式 表达式:  字符串, 标识符, 赋值语句, 数组 数组: [ 数组成员 ,。。。] 数组成员: 赋值语句, 表达式   而分析匹配的括号,只是上面分析的一个副产品。######语法是没有歧义的啊: 1. [ ] 可以包含任何字符,但是出现在 ' '单引号中的 [ ] 视为普通字符; 2. [ ] 可以嵌套 3. [ ] 必须配对###### 引用来自“李勇2”的答案 语法解析,首先要保证语法是没有歧义的; 这个例子就有些诡异: [ b=2, c=3 [, d=4] ] 如果是 [b=2, c=3, [d=4]] 就比较好 首先需要找到有哪些词法单元(终结符): 标识符 ID 整数 ' 单引号 \ 反斜杠 =赋值符号 [ 左中括号 ] 右中括号   再看有哪些语法单元(非终结符): 转意字符: \+单个字符 字符串: '任意字符或者转意字符' 赋值语句: 标识符 = 表达式 表达式:  字符串, 标识符, 赋值语句, 数组 数组: [ 数组成员 ,。。。] 数组成员: 赋值语句, 表达式   而分析匹配的括号,只是上面分析的一个副产品。 匹配的时候可能会存在冲突, 所以就需要给这些规则定一些优先级, 在有冲突的时候,用于选择某条规则
kun坤 2020-05-26 11:12:17 0 浏览量 回答数 0

回答

我遇到过和楼主相似的问题,我们当时要把数据库中存储的告警单(大小不确定,几K~十几M不等)页面显示给管理员。 遇到的问题是,偶然情况下会出现十几M的告警单,然后显示的时候就内存溢出了。后来解决方式是使用servlet,用最原始的out.println的方式把告警单输出给客户端,既解决内存溢出的问题,而且内存消耗也比较稳定。###### /** * BufferedReader *可以从字符输入流中读取文本,缓冲各个字符, *从而实现字符、数组和行的高效读取. */ ######nio?###### 引用来自“jqbmaster”的答案 /** * BufferedReader *可以从字符输入流中读取文本,缓冲各个字符, *从而实现字符、数组和行的高效读取. */ 各种XXBuffer不是万能药,而且BufferedReader和这个问题实在扯不上什么关系。。。 ######不放心可以自己定义字节数组,用字节流读取###### 你文件有多大就能读多大,只不过你要是把所有数据都放在内存中,拿就受内存限制。 ######要想指定一次读取的字节数,好像不能用bufferedreader吧
kun坤 2020-06-06 23:46:00 0 浏览量 回答数 0

回答

您可以在ECMA规范中查找比较算法(有关问题的ECMA-262,第三版的相关部分:11.9.3、9.1、8.6.2.6)。 如果将涉及的抽象算法转换回JS,则评估时2 == [2]基本上会发生以下情况: 2 === Number([2].valueOf().toString()) 其中valueOf(),数组返回数组本身,一元素数组的字符串表示形式是单个元素的字符串表示形式。 这也解释了第三个示例,因为[[[[[[[2]]]]]]].toString()它仍然只是字符串2。 如您所见,其中涉及很多幕后魔术,这就是为什么我通常只使用严格相等运算符的原因===。 第一个和第二个示例很容易理解,因为属性名称始终是字符串,因此 a[[2]] 相当于 a[[2].toString()] 这只是 a["2"] 请记住,在发生任何数组魔术之前,即使数字键也被视为属性名称(即字符串)。 问题来源于stack overflow
保持可爱mmm 2020-02-06 23:04:06 0 浏览量 回答数 0

云产品推荐

上海奇点人才服务相关的云产品 小程序定制 上海微企信息技术相关的云产品 国内短信套餐包 ECS云服务器安全配置相关的云产品 开发者问答 阿里云建站 自然场景识别相关的云产品 万网 小程序开发制作 视频内容分析 视频集锦 代理记账服务 阿里云AIoT