- ubuntu12.04环境下使用kvm ioctl接口实现最简单的虚拟机
- Ubuntu 通过无线网络安装Ubuntu Server启动系统后连接无线网络的方法
- 在Ubuntu上搭建网桥的方法
- ubuntu 虚拟机上网方式及相关配置详解
CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.
这篇CFSDN的博客文章Java面试题冲刺第一天--基础篇1由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.
操作字符串的类有:String、StringBuffer、StringBuilder.
String 和 StringBuffer、StringBuilder 的区别在于 String 声明的是不可变的对象,每次操作都会生成新的 String 对象,然后将指针指向新的 String 对象,而 StringBuffer、StringBuilder 可以在原有对象的基础上进行操作,所以在经常改变字符串内容的情况下最好不要使用 String.
而StringBuffer 和 StringBuilder 最大的区别在于,StringBuffer 是线程安全的,而 StringBuilder 是非线程安全的,但 StringBuilder 的性能却高于 StringBuffer,所以在单线程环境下推荐使用 StringBuilder,多线程环境下推荐使用 StringBuffer.
String | StringBuffer | StringBuilder | |
---|---|---|---|
类是否可变 | 不可变(Final) | 可变 | 可变 |
功能介绍 | 每次对String的操作都会在“常量池”中生成新的String对象 | 任何对它指向的字符串的操作都不会产生新的对象。每个StringBuffer对象都有一定的缓冲区容量,字符串大小没有超过容量时,不会分配新的容量,当字符串大小超过容量时,自动扩容 | 功能与StringBuffer相同,相比少了同步锁,执行速度更快 |
线程安全性 | 线程安全 | 线程安全 | 线程不安全 |
使用场景推荐 | 单次操作或循环外操作字符串 | 多线程操作字符串 | 单线程操作字符串 |
。
。
。
StringBulider > StringBuffer > String 。
String <(StringBuffer,StringBuilder)的原因?
从上面的名字可以看到,String是"字符串常量",也就是不可改变的对象。源码如下:
public final class String{}
对于上面这句话的理解你可能会产生这样一个疑问 ,比如这段代码:
String str = "唐伯虎";str = str + "点香烟";System.out.print(str); // result : "唐伯虎点香烟"
我们明明改变了String型的变量str啊,为什么说是没有改变呢?我们来看一下这张对String操作时内存变化的图:
我们可以看到,初始String值为"唐伯虎",然后在这个字符串后面加上新的字符串"点香烟",这个过程是需要重新在栈堆内存中开辟内存空间的,最终得到了"唐伯虎点香烟"字符串也相应的需要开辟内存空间,这样短短的两个字符串,却需要开辟三次内存空间,不得不说这是对内存空间的极大浪费,执行效率同理.
为了应对经常性操作字符串的场景,Java才提供了其他两个操作字符串的类 ―― StringBuffer、StringBuilder.
他们俩均属于字符串变量,是可改变的对象,每当我们用它们对字符串做操作时,实际上是在一个对象上操作的,这样就不会像String一样创建一些而外的对象进行操作了,速度自然就相对快了.
我们一般在StringBuffer、StringBuild类上的主要操作是 append 和 insert 方法,这些方法允许被重载,以接受任意类型的数据。每个方法都能有效地将给定的数据转换成字符串,然后将该字符串的字符追加或插入到字符串缓冲区中。append 方法始终将这些字符添加到缓冲区的末端;而 insert 方法则在指定的点(index)添加字符.
String 类型和 StringBuffer、 StringBuild类型的主要性能区别其实在于 String 是不可变的对象(final), 因此在每次对 String 类型进行改变的时候其实都等同于在堆中生成了一个新的 String 对象,然后将指针指向新的 String 对象,这样不仅效率低下,而且大量浪费有限的内存空间,所以经常改变内容的字符串最好不要用 String 。因为每次生成对象都会对系统性能产生影响,特别是当内存中的无引用对象过多了以后, JVM 的 GC 开始工作,那速度是一定会相当慢的。另外当GC清理速度跟不上new String的速度时,还会导致内存溢出Error,会直接kill掉主程序!报错如下:
Caused by: java.lang.OutOfMemoryError: GC overhead limit exceeded 。
Exception in thread "I/O dispatcher 3797236" java.lang.OutOfMemoryError: GC overhead limit exceeded 。
。
StringBuffer和StringBuilder可以算是双胞胎了,这两者的方法没有很大区别。但在线程安全性方面,StringBuffer允许多线程进行字符操作。这是因为在源代码中StringBuffer的很多方法都被关键字synchronized 修饰了,而StringBuilder没有.
synchronized的含义: 。
每一个类对象都对应一把锁,当某个线程A调用类对象O中的synchronized方法M时,必须获得对象O的锁才能够执行M方法,否则线程A阻塞。一旦线程A开始执行M方法,将独占对象O的锁。使得其它需要调用O对象的M方法的线程阻塞。只有线程A执行完毕,释放锁后。那些阻塞线程才有机会重新调用M方法。这就是解决线程同步问题的锁机制。 > 了解了synchronized的含义以后,大家可能都会有这个感觉。多线程编程中StringBuffer比StringBuilder要安全多了 ,事实确实如此。如果有多个线程需要对同一个字符串缓冲区进行操作的时候,StringBuffer应该是不二选择.
注意:是不是String也不安全呢?事实上不存在这个问题,String是不可变的。线程对于堆中指定的一个String对象只能读取,无法修改。试问:还有什么不安全的呢?
实际应用场景中:
。
。
。
Error 和 Exception 都是 Throwable 的子类,在Java中只有Throwable类型的实例才可以被抛出或者捕获,它是异常处理机制的基本类型.
。
基本数据类型 == 比较的是值,引用数据类型 == 比较的是内存地址
)equals()
: 它的作用也是判断两个对象是否相等。但它一般有两种使用情况:情况1:类没有覆盖 equals() 方法。则通过 equals() 比较该类的两个对象时,等价于调用了Object类的equals() 方法,也就是通过“==”比较这两个对象.
// Object类中的equals() 方法public boolean equals(Object obj) { return (this == obj);}
情况2:类覆盖了 equals() 方法。一般,我们都会覆盖 equals() 方法来两个对象的内容相等;若它们的内容相等,则返回 true (即,认为这两个对象相等).
// String类中的equals() 方法,已覆盖,用于比较内容public boolean equals(Object anObject) { if (this == anObject) { return true; } if (anObject instanceof String) { String anotherString = (String)anObject; int n = value.length; if (n == anotherString.value.length) { char v1[] = value; char v2[] = anotherString.value; int i = 0; while (n-- != 0) { if (v1[i] != v2[i]) return false; i++; } return true; } } return false;}
。
举例说明:
重点说明:是否重写Object类中的equals方法,会对结果造成的影响 。
public static void main(String[] args) { // 字符串比较 String a = "陈哈哈"; String b = "陈哈哈"; if (a == b) {// true a==b System.out.println("a==b"); } if (a.equals(b)) {// true a.equals(b) System.out.println("a.equals(b)"); } // StringBuffer 对象比较,由于StringBuffer没有重写Object的equal方法,因此结果出现错误 StringBuffer c = new StringBuffer("陈哈哈"); StringBuffer d = new StringBuffer("陈哈哈"); if (c == d) {// false c != d System.out.println("c == d"); } else { System.out.println("c != d"); } if (c.equals(d)) { // false 调用了Object类的equal方法 System.out.println("StringBuffer equal true"); }else { System.out.println("StringBuffer equal false"); }}
object的equals方法是比较的对象的内存地址,而String的equals方法比较的是对象的值。
。
在重写equals()方法时,也有必要对hashCode()方法进行重写,尤其是当我们自定义一个类,想把该类的实例存储在集合中时。 。
hashCode方法的常规约定为:值相同的对象必须有相同的hashCode,也就是equals()结果为相同,那么hashcode也要相同,equals()结果为不相同,那么hashcode也不相同; 。
当我们使用equals方法比较说明对象相同,但hashCode不同时,就会出现两个hashcode值,比如在HashMap中,就会认为这是两个对象,因此会出现矛盾,说明equals方法和hashCode方法应该成对出现,当我们对equals方法进行重写时,也要对hashCode方法进行重写.
可以通过ide快捷键快速生成两个方法,假设现在有一个学生Student类,其中有 age 和 name 两个特征。生成代码如下:
@Overridepublic boolean equals(Object o){//首先比较两个的地址值是否相同,如果相同,那内容也一定相同 if(this == o) return true;//如果o为空值或者两个对象的类型是否相同,如果类型不同或者o为空值则内容一定不同 if(o == null || getClass() != o.getClass()) return false;//将object类型的实例强转为Student类型 Student student = (Student)o;//比较两个实例的age是否相同 if(age != student.age) return false;//在比较name是否相同 return name != null ? name.equals(student.name ) : student.name == null;}@Overridepublic int hashCode() { int result = age; result = 31 * result + (name != null ? name.hashCode() : 0); return result;}
。
本篇文章就到这里了,希望能给你带来帮助,也希望您能够多多关注我的更多内容! 。
原文链接:https://blog.csdn.net/qq_39390545/article/details/117423180 。
最后此篇关于Java面试题冲刺第一天--基础篇1的文章就讲到这里了,如果你想了解更多关于Java面试题冲刺第一天--基础篇1的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
我有两个关于这段代码的问题。 double*** pdata 和 int*** pmask 是什么意思?指向指针的指针?为什么或何时需要这样做? int 和 double 是不同的类型,double*
谁能用英文解释一下这是怎么回事? std::vector cats; //I get that cats is a vector of Cat objects if (std::find(cats.b
在C中,下列声明有区别吗: float DoSomething( const float arr[] ); 对比 float DoSomething( const float* arr ); 一个比另
我到 question 36我认为这很简单。像往常一样,我显然错了。我正在尝试在 Python 中执行此操作(因为我不知道 Python)。我的代码如下。我得到 19 作为输出,这显然是不正确的。我不
我已经通读了 MSDN 上的 Winsock2 文档,但如果有人能提供帮助,我仍然需要澄清一些事情。 我计划做一些类似于您在使用 WSAAsyncSelect() 时获得的设置,但使用一个单独的线程。
#include int main () { int *p = (int *)malloc((100*sizeof(int))); p++; free(p); /* do some
我想提供未知的“对象”并返回其成员之一的值。在 C# 中需要响应。 一般来说,我想我正在寻找这个方法的代码公共(public)静态对象 GetObjectMemberValue (object myO
由异常准确的 AI 提供支持的 20 个问题的简单在线游戏。 他们怎么猜得这么好? 最佳答案 您可以将其视为二进制搜索算法。在每次迭代中,我们都会提出一个问题,该问题应该会消除大约一半的可能单词选择。
拜托,有人可以解释一下吗: 如果文档说 STL std::vector finding element speed performace = O(ln(n)),这是什么意思。 O(ln(n)) - 什
我正在尝试通过遵循 Microsoft 为 ADSI API 和 Windows-RS crate 发布的 c++ 示例来使用 Rust 的事件目录。我不太明白这里发生了什么: https://doc
这是处理具有重复元素的单个列表的 nieve 案例,我在处理一些嵌套列表时遇到了麻烦,所以我想先写简单的案例。 所以我有: (defn packDuplicatesIntoLists [lis
我是新来的。我正在尝试解决此练习 Problem 18只是为了加强我的解决能力。我已经编码了答案。该任务要求“在 1,000,000 以下的质数中,有多少个数位之和等于两周中的天数?” (两周是 14
我正在尝试对POCO类中的某些字段进行索引,并将某些属性装饰为“忽略= true”,并且这些字段不应被索引,而应该被存储。我希望这些字段出现在搜索结果中,但不应作为索引。 我正在尝试对应索引的几个字段
我是编码的新手,正在尝试通过完成 Project Euler 问题来学习 Swift。我似乎有导致大量错误的不同版本的 Swift 代码。如果您对我的问题的格式有任何建议以供将来引用,请告诉我,谢谢。
对于problem statement在 google codejam 2008:第 1A 轮问题 3 In this problem, you have to find the last three
我是一名优秀的程序员,十分优秀!