Test2

本文详细解析了Java中的String、StringBuilder、StringBuffer的区别,Integer与int的区别,AbstractClass和Interface的区别等核心技术概念。同时还介绍了常见的RuntimeException、异常处理机制、Collection框架中的比较接口及List、Map、Set的特点。

1. String和StringBuffer、StringBuilder有什么区别?

1、可变性:
	简单的来说:String 类中使用 final 关键字字符数组保存字符串,`private final char value[]`,所以 String 对象是不可变的。
而StringBuilder 与 StringBuffer 都继承自 AbstractStringBuilder 类,在 AbstractStringBuilder 中也是使用字符数组保存字符串`char[]value` 但是没有用 final 关键字修饰,所以这两种对象都是可变的。
StringBuilder 与 StringBuffer 的构造方法都是调用父类构造方法也就是 Abstract StringBuilder 实现的,大家可以自行查阅源码。
AbstractStringBuilder:
	abstract class AbstractStringBuilder implements Appendable, CharSequence {
        char[] value;
        int count;
        AbstractStringBuilder() {
        }
        AbstractStringBuilder(int capacity) {
            value = new char[capacity];
        }
        
 2、线程安全:
 	String 中的对象是不可变的,也就可以理解为常量,线程安全。AbstractStringBuilder 是 StringBuilder 与 StringBuffer 的公
 	共父类,定义了一些字符串的基本操作,如 expandCapacity、append、insert、indexOf 等公共方法。StringBuffer 对方法加了同步锁或者对调用的方法加了同步锁,所以是线程安全的。StringBuilder 并没有对方法进行加同
 	步锁,所以是非线程安全的。
 	
 3、性能:
 	每次对 String 类型进行改变的时候,都会生成一个新的 String 对象,然后将指针指向新的 String 对象。StringBuffer 每次都会
 	对 StringBuffer 对象本身进行操作,而不是生成新的对象并改变对象引用。相同情况下使用 StringBuilder 相比使用 StringBuffer 
 	仅能获得 10%~15% 左右的性能提升,但却要冒多线程不安全的风险。
 	
 总结:
 	1. 操作少量的数据 = String
	2. 单线程操作字符串缓冲区下操作大量数据 = StringBuilder
	3. 多线程操作字符串缓冲区下操作大量数据 = StringBuffer

2. 简述 Integer与int的区别

1Integerint的包装类,int则是java的一种基本数据类型 
2Integer变量必须实例化后才能使用,而int变量不需要 
3Integer实际是对象的引用,当new一个Integer时,实际上是生成一个指针指向此对象;而int则是直接存储数据值 
4Integer的默认值是nullint的默认值是0

3. Abstract Class和Interface有什么区别?

实现:抽象类的子类使用 extends 来继承;接口必须使用 implements 来实现接口。
构造函数:抽象类可以有构造函数;接口不能有。
main 方法:抽象类可以有 main 方法,并且我们能运行它;接口不能有 main 方法。
实现数量:类可以实现很多个接口;但是只能继承一个抽象类。
访问修饰符:接口中的方法默认使用 public 修饰;抽象类中的方法可以是任意访问修饰符。

4. 请写出你最常见到的5个Runtime Exception。

NullPointerException:当应用程序试图访问空对象时,则抛出该异常。
SQLException:提供关于数据库访问错误或其他错误信息的异常。
IndexOutOfBoundsException:指示某排序索引(例如对数组、字符串或向量的排序)超出范围时抛出。 
NumberFormatException:当应用程序试图将字符串转换成一种数值类型,但该字符串不能转换为适当格式时,抛出该异常。
FileNotFoundException:当试图打开指定路径名表示的文件失败时,抛出此异常。
IOException:当发生某种I/O异常时,抛出此异常。此类是失败或中断的I/O操作生成的异常的通用类。
ClassCastException:当试图将对象强制转换为不是实例的子类时,抛出该异常。
ArrayStoreException:试图将错误类型的对象存储到一个对象数组时抛出的异常。
IllegalArgumentException:抛出的异常表明向方法传递了一个不合法或不正确的参数。
ArithmeticException:当出现异常的运算条件时,抛出此异常。例如,一个整数“除以零”时,抛出此类的一个实例。 
NegativeArraySizeException:如果应用程序试图创建大小为负的数组,则抛出该异常。
NoSuchMethodException:无法找到某一特定方法时,抛出该异常。
SecurityException:由安全管理器抛出的异常,指示存在安全侵犯。
UnsupportedOperationException:当不支持请求的操作时,抛出该异常。
RuntimeExceptionRuntimeException:是那些可能在Java虚拟机正常运行期间抛出的异常的超类。

5. JAVA语言如何进行异常处理,关键字:throws,throw,try,catch,finally分别代表什么意义?在try块中可以抛出异常吗?

throws:声明异常
throw:抛出异常
try:可能出现异常的代码块
catch:捕获出现的异常
finally:不管怎么样都会执行的代码块
在try中可以抛出异常,并且被catch捕获

6. Collection框架中实现比较要实现什么接口?

 ComparableComparator接口

 如果一个类的不同对象需要比较大小,那么就需要实现这两个接口,根据业务需求定义规则。

 使用区别:
 (1)Comparable接口

 是需要比较的类实现自己实现,例如:定义的Student类需要比较,需要Student类自己实现这个接口,实现ComParaTo()方法。

 (2)Comparator接口

 自己定义一个比较容器,去实现这个接口(实现compare方法),然后在集合生成的时候,用一个比较对象做参数,跟集合绑定。

7. List、Map、Set三个接口,存取元素时,各有什么特点?

List接口特点:
1. 它是一个元素存取有序的集合。例如,存元素的顺序是112233。那么集合中,元素的存储就是按照112233的顺序完成的)。
2. 它是一个带有索引的集合,通过索引就可以精确的操作集合中的元素(与数组的索引是一个道理)。
3. 集合中可以有重复的元素,通过元素的equals方法,来比较是否为重复的元素。

Set接口特点
java.util.Set接口和java.util.List接口一样,同样继承自Collection接口,它与Collection接口中的方法基本一致,并没有对
Collection接口进行功能上的扩充,只是比Collection接口更加严格了。与List接口不同的是,Set接口中元素无序(个别有序-
LinkedHashSet),并且都会以某种规则保证存入的元素不出现重复。

Map接口特点
1.Map中的集合,元素是成对存在的(理解为夫妻)。每个元素由键与值两部分组成,通过键可以找对所对应的值。
2.Collection`中的集合称为单列集合,Map中的集合称为双列集合。
3.需要注意的是,Map中的集合不能包含重复的键,值可以重复;每个键只能对应一个值。

8. Set里的元素是不能重复的,那么用什么方法来区分重复与否呢? 是用==还是equals()? 它们有何区别?

Set集合一般是重写equals方法和hashcode方法来让元素不重复
== 对于基本类型来说是值比较,对于引用类型来说是比较的是引用;而 equals 默认情况下是引用比较,只是很多类重新了 equals 方法,
比如 StringInteger 等把它变成了值比较,所以一般情况下 equals 比较的是值是否相等。

9. 简述ArrayList,Vector, LinkedList的存储性能和特性.

ArrayListVector都是基于存储元素的对象数组来实现的:
	1Vector默认扩充为原来的两倍(每次扩充空间的大小可以设置),ArrayList默认扩充为原来的1.5倍。
	2Vector是线程安全的,ArrayList不是线程安全的
LinkedList是采用双向列表来实现的,对数据的索引需要从列表头开始遍历,因此用于随机访问则效率比较低,但是插入元素时不需要对数据
进行移动,因此插入效率较高。同时,LinkedList是非线程安全的容器

10、Map中数据的迭代方式有哪些?

2种迭代方法
1.通过keySet方法取出Map的键到Set集合中,然后通过遍历键取到对应的值,从而迭代出Map集合
2.通过Map.Entry<T,U>方法取出Entry,然后遍历Entry,getKey取出键值,getValue取出对应的值。

11、说说怎么进行日期格式化?

Java中通过DateFormat进行格式化日期,列如:
		Date date = new Date();
        DateFormat dateFormat = new SimpleDateFormat("yyyy年MM月dd日");
        String d = dateFormat.format(date);
        System.out.println(d);

12、简述Object中hashcode、equals理解

hashCode()介绍:
	hashCode() 的作用是获取哈希码,也称为散列码;它实际上是返回一个int整数。这个哈希码的作用是确定该对象在哈希表中的索引位置。hashCode() 定义在JDK的Object.java中,这就意味着Java中的任何类都包含hashCode() 函数。
散列表存储的是键值对(key-value),它的特点是:能根据“键”快速的检索出对应的“值”。这其中就利用到了散列码!(可以快速找到所需要的对象)

为什么要有 hashCode
	我们以“HashSet如何检查重复”为例子来说明为什么要有hashCode:
	当你把对象加入HashSet时,HashSet 会先计算对象的hashcode值来判断对象加入的位置,同时也会与其他已经加入的对象的hashcode
	值作比较,如果没有相符的hashcode,HashSet会假设对象没有重复出现。但是如果发现有相同 hashcode 值的对象,这时会调用 equals()方法来检查 hashcode 相等的对象是否真的相同。如果两者相同,HashSet 就不会让其加入操作成功。如果不同的话,就会重新散列到其他位置。(摘自我的Java启蒙书《Head first java》第二版)。
	这样我们就大大减少了 equals 的次数,相应就大大提高了执行速度。

hashCode()与equals()的相关规定:
	1. 如果两个对象相等,则hashcode一定也是相同的
	2. 两个对象相等,对两个对象分别调用equals方法都返回true
	3. 两个对象有相同的hashcode值,它们也不一定是相等的
	4. 因此,equals 方法被覆盖过,则 hashCode 方法也必须被覆盖
	5. hashCode() 的默认行为是对堆上的对象产生独特值。如果没有重写 hashCode(),则该 class 的两个对象无论如何都不会相等(即使这两个对象指向相同的数据)
<think> 我们正在处理用户关于目录重命名的问题。根据用户提供的引用和之前的上下文,用户希望将目录test重命名为test2。 引用中提到:执行命令:mv test test3 #给目录test重命名 因此,我们可以推断,使用mv命令可以实现目录的重命名。 步骤: 1. 确认当前目录位置:确保在包含test目录的父目录下操作,或者使用绝对路径。 2. 使用mv命令:mv 旧目录名 新目录名 具体命令: mv test test2 注意: - 如果当前目录下已经存在名为test2的目录或文件,那么mv命令会覆盖目标(如果是目录,则要求目标为空目录,或者使用-f选项强制覆盖?但实际上,mv对目录的覆盖行为与文件不同,如果目标目录已存在,则会将源目录移动到目标目录里面。所以这里需要特别注意:目标名称不能已经存在,除非你想将test目录移动到test2目录里面)。 - 实际上,重命名目录时,目标目录名不能存在。如果存在,则无法直接重命名(会报错:目录已存在)。因此,在重命名之前,要确保目标名称不存在。 所以,正确的操作是: mv test test2 # 将目录test重命名为test2 如果test2已经存在,并且是一个目录,那么上面的命令会将test目录移动到test2目录下(即成为test2/test)。这不是我们想要的。因此,在重命名之前,我们需要确保test2不存在。 如果用户确实需要覆盖已存在的目录,那么需要先删除目标目录(如果目标目录中有重要文件,需要先备份)或者使用其他方法。 但是,用户的问题只是重命名,所以我们假设目标名称test2不存在。 操作示例: $ ls test $ mv test test2 $ ls test2 如果不在当前目录,可以使用绝对路径: mv /path/to/test /path/to/test2 权限问题:如果目录在当前用户没有写权限的目录下,则需要使用sudo。 因此,根据用户需求,直接给出命令: 命令: mv test test2 如果出现权限问题,则使用: sudo mv test test2 另外,引用[1]中给出了一个例子:执行命令:mv test test3 #给目录test重命名。所以这个操作是可行的。 生成相关问题: 1. 如何同时移动多个目录并重命名? 2. 如果目标目录已经存在,如何安全地重命名目录以避免覆盖? 3. 如何递归地重命名目录及其子目录中的文件? 4. 在Linux中,如何批量重命名多个目录? 回答用户: 您可以使用mv命令将test目录重命名为test2。具体命令为:`mv test test2`。请注意,如果目标目录test2已经存在,则此操作会将test目录移动到test2目录中(即成为test2/test)。因此,请确保test2不存在。如果操作需要权限,请使用sudo。 引用用户提供的引用[1]作为参考。 </think> ### 如何将test目录重命名为test2 在Linux系统中,使用`mv`命令可以轻松完成目录重命名操作。以下是详细步骤: #### 📌 基本重命名命令 ```bash mv test test2 ``` #### 🔍 操作详解 1. **检查当前目录** 确保在包含`test`目录的父目录下操作: ```bash ls -l # 确认test目录存在 ``` 2. **执行重命名** ```bash mv test test2 # 将test重命名为test2 ``` 3. **验证结果** ```bash ls -l # 查看新目录test2 ``` #### ⚠️ 注意事项 1. **目录存在性检查** - 如果目标名称`test2`已存在,会显示错误: `mv: cannot move 'test' to 'test2': File exists` - 安全操作建议: ```bash mv -i test test2 # 交互式确认覆盖 ``` 2. **跨文件系统移动** 当源目录(test)和目标目录(test2)在不同分区时: ```bash mv -T test test2 # 强制作为目录操作 ``` 3. **权限问题** - 如果目录属于其他用户: ```bash sudo mv test test2 # 使用管理员权限 ``` #### 📊 操作示意图 ```mermaid graph LR A[操作前] -->|mv 命令| B[操作后] A --> C[/test/] B --> D[/test2/] C -.重命名.-> D ``` #### 💡 高级技巧 1. **保留属性** 保留原目录的修改时间和权限: ```bash mv -v --preserve=all test test2 ``` 2. **批量重命名** 使用通配符重命名多个目录: ```bash for d in test_*; do mv "$d" "${d/_/}"; done # 移除下划线 ``` ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值