1. 常见构造器,方法Random类
Java中存在着两种Random函数:
一、java.lang.Math.Random;
调用这个Math.Random()函数能够返回带正号的double值,该值大于等于0.0且小于1.0,即取值范围是 [0.0,1.0)的左闭右开区间,返回值是一个伪随机选择的数,在该范围内(近似)均匀分布。例子如下:
1 public static void main(String[] args) {
2 // 结果是个double类型的值,区间为[0.0,1.0)
3 System.out.println("Math.random()=" + Math.random());
4 int num = (int) (Math.random() * 3);
5 // 注意不要写成(int)Math.random()*3,这个结果为0或1,因为先执行了强制转换
6 System.out.println("num=" + num);
7 }
8 //结果
9 //Math.random()=0.44938147153848396
10 //num=1
二、java.util.Random
下面是Random()的两种构造方法:
Random():创建一个新的随机数生成器。
Random(long seed):使用单个 long 种子创建一个新的随机数生成器。
你在创建一个Random对象的时候可以给定任意一个合法的种子数,种子数只是随机算法的起源数字, 和生成的随机数的区间没有任何关系。
如下面的Java代码:
【演示一】
在没带参数构造函数生成的Random对象的种子缺省是当前系统时间的毫秒数。
rand.nextInt(100)中的100是随机数的上限,产生的随机数为0-100的整数,不包括100。
1 public static void main(String[] args) {
2 Random rand =new Random();
3 int i=rand.nextInt(100);
4 System.out.println(i);
5 }
【演示二】
对于种子相同的Random对象,生成的随机数序列是一样的。
public static void main(String[] args) {
Random ran1 = new Random(25);
System.out.println("使用种子为25的Random对象生成[0,100)内随机整数序列: ");
for (int i = 0; i < 10; i++) {
System.out.print(ran1.nextInt(100) + " ");
}
System.out.println();
}
日期时间类
1、Date类
java.util 包提供了 Date 类来封装当前的日期和时间。
Date 类提供两个构造函数来实例化 Date 对象。
第一个构造函数使用当前日期和时间来初始化对象。
第二个构造函数接收一个参数,该参数是从1970年1月1日起的毫秒数。
Date对象创建以后,可以调用下面的方法:
2、SimpleDateFormat
【演示:使用 SimpleDateFormat 格式化日期】
SimpleDateFormat 是一个以语言环境敏感的方式来格式化和分析日期的类。
SimpleDateFormat 允许你选择任何用户自定义日期时间格式来运行。例如:
1 public class test {
2 public static void main(String[] args) {
3 Date dNow = new Date( );
4 SimpleDateFormat ft = new SimpleDateFormat ("yyyy-MM-dd hh:mm:ss");
5 System.out.println("当前时间为: " + ft.format(dNow));
6 // 当前时间为: 2021-03-07 03:17:45
7 }
8 }
其中 yyyy 是完整的公元年,MM 是月份,dd 是日期,HH:mm:ss 是时、分、秒。
注意:有的格式大写,有的格式小写,例如 MM 是月份,mm 是分;HH 是 24 小时制,而 hh 是 12 小时 制。
时间模式字符串用来指定时间格式。在此模式中,所有的 ASCII 字母被保留为模式字母,定义如下:
【时间休眠:休眠(sleep)】
sleep()使当前线程进入停滞状态(阻塞当前线程),让出CPU的使用、目的是不让当前线程独自霸占该进程所获的CPU资源,以留一定时间给其他线程执行的机会。
你可以让程序休眠一毫秒的时间或者到您的计算机的寿命长的任意段时间。例如,下面的程序会休眠3 秒:
1 public class test {
2 public static void main(String[] args) {
3 try {
4 System.out.println(new Date( ) + "\n");
5 Thread.sleep(1000*3); // 休眠3秒
6 System.out.println(new Date( ) + "\n");
7 } catch (Exception e) {
8 System.out.println("Got an exception!");
9 }
10 }
11 }
3、Calendar类
我们现在已经能够格式化并创建一个日期对象了,但是我们如何才能设置和获取日期数据的特定部分 呢,比如说小时,日,或者分钟? 我们又如何在日期的这些部分加上或者减去值呢? 答案是使用Calendar 类。Date中有很多方法都已经废弃了!
Calendar类的功能要比Date类强大很多,而且在实现方式上也比Date类要复杂一些。
Calendar类是一个抽象类,在实际使用时实现特定的子类的对象,创建对象的过程对程序员来说是透明的,只需要使用getInstance方法创建即可。
创建一个代表系统当前日期的Calendar对象
1 public class test {
2 public static void main(String[] args) {
3 Calendar c = Calendar.getInstance();//默认是当前日期
4 System.out.println(c);
5 }
6 }
7
8 java.util.GregorianCalendar[time=1615101654795,areFieldsSet=true,areAllFieldsSet=true,
lenient=true,zone=sun.util.calendar.ZoneInfo[id="Asia/Shanghai",offset=28800000,dstSavings=0,useDaylight=false,transitions=19,lastRule=null],firstDayOfWeek=1,minimalDaysInFirstWeek=1,ERA=1,YEAR=2021,MONTH=2,WEEK_OF_YEAR=11,WEEK_OF_MONTH=2,DAY_OF_MONTH=7,DAY_OF_YEAR=66,DAY_OF_WEEK=1,DAY_OF_WEEK_IN_MONTH=1,AM_PM=1,HOUR=3,HOUR_OF_DAY=15,MINUTE=20,SECOND=54,MILLISECOND=795,ZONE_OFFSET=28800000,DST_OFFSET=0]
创建一个指定日期的Calendar对象
使用Calendar类代表特定的时间,需要首先创建一个Calendar的对象,然后再设定该对象中的年月日参数来完成。
1 //创建一个代表2019年4月27日的Calendar对象
2 Calendar c1 = Calendar.getInstance();
3 c1.set(2019, 4 - 1, 27);
Calendar类对象字段类型
Calendar类中用以下这些常量表示不同的意义,jdk内的很多类其实都是采用的这种思想
1 // 获得年份
2 int year = c1.get(Calendar.YEAR);
3 // 获得月份
4 int month = c1.get(Calendar.MONTH) + 1;
5 // 获得日期
6 int date = c1.get(Calendar.DATE);
7 // 获得小时
8 int hour = c1.get(Calendar.HOUR_OF_DAY);
9 // 获得分钟
10 int minute = c1.get(Calendar.MINUTE);
11 // 获得秒
12 int second = c1.get(Calendar.SECOND);
13 // 获得星期几(注意(这个与Date类是不同的):1代表星期日、2代表星期1、3代表星期二,以此类推)
14 int day = c1.get(Calendar.DAY_OF_WEEK);
String类
1、string概述
在API中是这样描述:
String 类代表字符串。Java 程序中的所有字符串字面值(如 "abc" )都作为此类的实例实现。 字符串是常量;它们的值在创建之后不能更改。字符串缓冲区支持可变的字符串。因为 String 对象是不可变的, 所以可以共享。
【演示:查看String源码】
1 public final class String
2 implements java.io.Serializable, Comparable<String>, CharSequence {}
【String的成员变量】
1 //String的属性值
2 private final char value[];
3 //数组被使用的开始位置
4 private final int offset;
5 //String中元素的个数
6 private final int count;
7 //String类型的hash值
8 private int hash; // Default to 0
9
10 private static final long serialVersionUID = -6849794470754667710L;
11 private static final ObjectStreamField[] serialPersistentFields =
12 new ObjectStreamField[0];
从源码看出String底层使用一个字符数组来维护的。
成员变量可以知道String类的值是final类型的,不能被改变的,所以只要一个值改变就会生成一个新的 String类型对象,存储String数据也不一定从数组的第0个元素开始的,而是从offset所指的元素开始。
【String的构造方法】
1 String()
2 //初始化一个新创建的 String 对象,使其表示一个空字符序列。
3 String(byte[] bytes)
4 //通过使用平台的默认字符集解码指定的 byte 数组,构造一个新的 String。
5 String(byte[] bytes, Charset charset)
6 //通过使用指定的 charset 解码指定的 byte 数组,构造一个新的 String。
7 String(byte[] bytes, int offset, int length)
8 //通过使用平台的默认字符集解码指定的 byte 子数组,构造一个新的 String。
9 String(byte[] bytes, int offset, int length, Charset charset)
10 //通过使用指定的 charset 解码指定的 byte 子数组,构造一个新的 String。
11 String(byte[] bytes, int offset, int length, String charsetName)
12 //通过使用指定的字符集解码指定的 byte 子数组,构造一个新的 String。
13 String(byte[] bytes, String charsetName)
14 //通过使用指定的 charset 解码指定的 byte 数组,构造一个新的 String。
15 String(char[] value)
16 //分配一个新的 String,使其表示字符数组参数中当前包含的字符序列。
17 String(char[] value, int offset, int count)
18 //分配一个新的 String,它包含取自字符数组参数一个子数组的字符。
19 String(int[] codePoints, int offset, int count)
20 //分配一个新的 String,它包含 Unicode 代码点数组参数一个子数组的字符。
21 String(String original)
22 //初始化一个新创建的 String 对象,使其表示一个与参数相同的字符序列;换句话说,新创建
23 的字符串是该参数字符串的副本。
24 String(StringBuffer buffer)
25 //分配一个新的字符串,它包含字符串缓冲区参数中当前包含的字符序列。
26 String(StringBuilder builder)
27 //分配一个新的字符串,它包含字符串生成器参数中当前包含的字符序列。
2、创建字符串对象方式
直接赋值方式创建对象是在方法区的常量池
String str="hello";//直接赋值的方式
通过构造方法创建字符串对象是在堆内存
String str=new String("hello");//实例化的方式
【两种实例化方式的比较】
1. 编写代码比较
1 public class test {
2 public static void main(String[] args) {
3 String str1 = "Lance";
4 String str2 = new String("Lance");
5 String str3 = str2; //引用传递,str3直接指向st2的堆内存地址
6 String str4 = "Lance";
7 /**
8 * ==:
9 * 基本数据类型:比较的是基本数据类型的值是否相同
10 * 引用数据类型:比较的是引用数据类型的地址值是否相同
11 * 所以在这里的话:String类对象==比较,比较的是地址,而不是内容
12 */
13 System.out.println(str1==str2);//false
14 System.out.println(str1==str3);//false
15 System.out.println(str3==str2);//true
16 System.out.println(str1==str4);//true
17
18 }
19 }
1. 内存图分析
可能这里还是不够明显,构造方法实例化方式的内存图:String str = new String("Hello");
首先:
当我们再一次的new一个String对象时:
【字符串常量池】
在字符串中,如果采用直接赋值的方式(String str="Lance")进行对象的实例化,则会将匿名对象 “Lance”放入对象池,每当下一次对不同的对象进行直接赋值的时候会直接利用池中原有的匿名对象,我 们可以用对象手工入池;
1 String str =new String("Lance").intern();//对匿名对象"hello"进行手工入池操作
2 String str1="Lance";
3 System.out.println(str==str1);//true
【避免空指向】
首先了解: == 和public boolean equals()比较字符串的区别
==在对字符串比较的时候,对比的是内存地址,而equals比较的是字符串内容,在开发的过程中, equals()通过接受参数,可以避免空指向。
String str = null;
if(str.equals("hello")){//此时会出现空指向异常
...
}
if("hello".equals(str)){//此时equals会处理null值,可以避免空指向异常
...
}
【String类对象一旦声明则不可以改变;而改变的只是地址,原来的字符串还是存在的,并且产生垃圾】
3、String常用的方法
1、String的判断
boolean equals(Object obj):比较字符串的内容是否相同
boolean equalsIgnoreCase(String str): 比较字符串的内容是否相同,忽略大小写
boolean startsWith(String str): 判断字符串对象是否以指定的str开头
boolean endsWith(String str): 判断字符串对象是否以指定的str结尾
2、String的截取
int length():获取字符串的长度,其实也就是字符个数
char charAt(int index):获取指定索引处的字符
int indexOf(String str):获取str在字符串对象中第一次出现的索引
String substring(int start):从start开始截取字符串
String substring(int start,int end):从start开始,到end结束截取字符串。包括start,不包括end
3、String的转换
1 char[] toCharArray():把字符串转换为字符数组
2 String toLowerCase():把字符串转换为小写字符串
3 String toUpperCase():把字符串转换为大写字符串
4、其他方法
去除字符串两端空格:String trim()
按照指定符号分割字符串:String[] split(String str)
4、String的不可变性、
当我们去阅读源代码的时候,会发现有这样的一句话:
Strings are constant; their values cannot be changed after they are created.
意思就是说:String是个常量,从一出生就注定不可变。
我想大家应该就知道为什么String不可变了,String类被final修饰,官方注释说明创建后不能被改变,但 是为什么String要使用final修饰呢?
【了解一个经典的面试题】
1 public class test {
2 public static void main(String[] args) {
3 String a = "abc";
4 String b = "abc";
5 String c = new String("abc");
6 System.out.println(a==b); //true
7 System.out.println(a.equals(b)); //true
8 System.out.println(a==c); //false
9 System.out.println(a.equals(c)); //true
10 }
11 }
内存图分析:
【分析】
因为String太过常用,JAVA类库的设计者在实现时做了个小小的变化,即采用了享元模式,每当生成一个新内容的字符串时,他们都被添加到一个共享池中,当第二次再次生成同样内容的字符串实例时,就共享此对象,而不是创建一个新对象,但是这样的做法仅仅适合于通过=符号进行的初始化。
需要说明一点的是,在object中,equals()是用来比较内存地址的,但是String重写了equals()方 法,用来比较内容的,即使是不同地址,只要内容一致,也会返回true,这也就是为什么a.equals(c)返 回true的原因了。
5、字符串常量池
【字符串常量池概述】
1. 常量池表(Constant_Pool table)
Class文件中存储所有常量(包括字符串)的table。这是Class文件中的内容,还不是运行时的内容,不要理解它是个池子,其实就是Class文件中的字节码指令。
1. 运行时常量池(Runtime Constant Pool)
JVM内存中方法区的一部分,这是运行时的内容。这部分内容(绝大部分)是随着JVM运行时候,从常 量池转化而来,每个Class对应一个运行时常量池。上一句中说绝大部分是因为:除了 Class中常量池内 容,还可能包括动态生成并加入这里的内容。
1. 字符串常量池(String Pool)
这部分也在方法区中,但与Runtime Constant Pool不是一个概念,String Pool是JVM实例全局共享 的,全局只有一个。JVM规范要求进入这里的String实例叫“被驻留的interned string”,各个JVM可以有 不同的实现,HotSpot是设置了一个哈希表StringTable来引用堆中的字符串实例,被引用就是被驻留
【亨元模式】
其实字符串常量池这个问题涉及到一个设计模式,叫“享元模式”,顾名思义 - - - > 共享元素模式 也就是说:一个系统中如果有多处用到了相同的一个元素,那么我们应该只存储一份此元素,而让所有 地方都引用这一个元素 Java中String部分就是根据享元模式设计的,而那个存储元素的地方就叫做“字符串常量池 - String Pool”
【详细分析】
举例:
1 使用String s = new String("hello");会创建几个对象
2 答:会创建2个对象
3 首先,出现了字面量"hello",那么去String Pool中查找是否有相同字符串存在,因为程序就这一行
4 代码所以肯定没有,那么就在Java Heap中用字面量"hello"首先创建1个String对象。
5 接着,new String("hello"),关键字new又在Java Heap中创建了1个对象,然后调用接收String
6 参数的构造器进行了初始化。最终s的引用是这个String对象.
StringBuilder 和 StringBuffer
1、概述
【演示:查看源码及API文档】
1 public final class StringBuilder
2 extends AbstractStringBuilder
3 implements java.io.Serializable, CharSequence{
4 }
StringBuilder 是一个可变的字符序列。它继承于AbstractStringBuilder,实现了CharSequence接口。
StringBuffer 也是继承于AbstractStringBuilder的子类;但是,StringBuilder和StringBuffer不同,前者 是非线程安全的,后者是线程安全的。
StringBuilder 和 CharSequence之间的关系图如下:
【源码概览】
1 package java.lang;
2
3
4 /**
5 * A mutable sequence of characters. This class provides an API compatible
6 * with {@code StringBuffer}, but with no guarantee of synchronization.
7 * This class is designed for use as a drop-in replacement for
8 * {@code StringBuffer} in places where the string buffer was being
9 * used by a single thread (as is generally the case). Where possible,
10 * it is recommended that this class be used in preference to
11 * {@code StringBuffer} as it will be faster under most implementations.
12 *
13 * <p>The principal operations on a {@code StringBuilder} are the
14 * {@code append} and {@code insert} methods, which are
15 * overloaded so as to accept data of any type. Each effectively
16 * converts a given datum to a string and then appends or inserts the
17 * characters of that string to the string builder. The
18 * {@code append} method always adds these characters at the end
19 * of the builder; the {@code insert} method adds the characters at
20 * a specified point.
21 * <p>
22 * For example, if {@code z} refers to a string builder object
23 * whose current contents are "{@code start}", then
24 * the method call {@code z.append("le")} would cause the string
25 * builder to contain "{@code startle}", whereas
26 * {@code z.insert(4, "le")} would alter the string builder to
27 * contain "{@code starlet}".
28 * <p>
29 * In general, if sb refers to an instance of a {@code StringBuilder},
30 * then {@code sb.append(x)} has the same effect as
31 * {@code sb.insert(sb.length(), x)}.
32 * <p>
33 * Every string builder has a capacity. As long as the length of the
34 * character sequence contained in the string builder does not exceed
35 * the capacity, it is not necessary to allocate a new internal
36 * buffer. If the internal buffer overflows, it is automatically made larger.
37 *
38 * <p>Instances of {@code StringBuilder} are not safe for
39 * use by multiple threads. If such synchronization is required then it is
40 * recommended that {@link java.lang.StringBuffer} be used.
41 *
42 * <p>Unless otherwise noted, passing a {@code null} argument to a constructor
43 * or method in this class will cause a {@link NullPointerException} to be
44 * thrown.
45 *
46 * @author Michael McCloskey
47 * @see java.lang.StringBuffer
48 * @see java.lang.String
49 * @since 1.5
50 */
51 public final class StringBuilder
52 extends AbstractStringBuilder
53 implements java.io.Serializable, CharSequence
54 {
55
56 /** use serialVersionUID for interoperability */
57 static final long serialVersionUID = 4383685877147921099L;
58
59 /**
60 * Constructs a string builder with no characters in it and an
61 * initial capacity of 16 characters.
62 */
63 public StringBuilder() {
64 super(16);
65 }
66
67 /**
68 * Constructs a string builder with no characters in it and an
69 * initial capacity specified by the {@code capacity} argument.
70 *
71 * @param capacity the initial capacity.
72 * @throws NegativeArraySizeException if the {@code capacity}
73 * argument is less than {@code 0}.
74 */
75 public StringBuilder(int capacity) {
76 super(capacity);
77 }
78
79 /**
80 * Constructs a string builder initialized to the contents of the
81 * specified string. The initial capacity of the string builder is
82 * {@code 16} plus the length of the string argument.
83 *
84 * @param str the initial contents of the buffer.
85 */
86 public StringBuilder(String str) {
87 super(str.length() + 16);
88 append(str);
89 }
90
91 /**
92 * Constructs a string builder that contains the same characters
93 * as the specified {@code CharSequence}. The initial capacity of
94 * the string builder is {@code 16} plus the length of the
95 * {@code CharSequence} argument.
96 *
97 * @param seq the sequence to copy.
98 */
99 public StringBuilder(CharSequence seq) {
100 this(seq.length() + 16);
101 append(seq);
102 }
103
104 @Override
105 public StringBuilder append(Object obj) {
106 return append(String.valueOf(obj));
107 }
108
109 @Override
110 public StringBuilder append(String str) {
111 super.append(str);
112 return this;
113 }
114
115 /**
116 * Appends the specified {@code StringBuffer} to this sequence.
117 * <p>
118 * The characters of the {@code StringBuffer} argument are appended,
119 * in order, to this sequence, increasing the
120 * length of this sequence by the length of the argument.
121 * If {@code sb} is {@code null}, then the four characters
122 * {@code "null"} are appended to this sequence.
123 * <p>
124 * Let <i>n</i> be the length of this character sequence just prior to
125 * execution of the {@code append} method. Then the character at index
126 * <i>k</i> in the new character sequence is equal to the character at
127 * index <i>k</i> in the old character sequence, if <i>k</i> is less than
128 * <i>n</i>; otherwise, it is equal to the character at index <i>k-n</i>
129 * in the argument {@code sb}.
130 *
131 * @param sb the {@code StringBuffer} to append.
132 * @return a reference to this object.
133 */
134 public StringBuilder append(StringBuffer sb) {
135 super.append(sb);
136 return this;
137 }
138
139 @Override
140 public StringBuilder append(CharSequence s) {
141 super.append(s);
142 return this;
143 }
144
145 /**
146 * @throws IndexOutOfBoundsException {@inheritDoc}
147 */
148 @Override
149 public StringBuilder append(CharSequence s, int start, int end) {
150 super.append(s, start, end);
151 return this;
152 }
153
154 @Override
155 public StringBuilder append(char[] str) {
156 super.append(str);
157 return this;
158 }
159
160 /**
161 * @throws IndexOutOfBoundsException {@inheritDoc}
162 */
163 @Override
164 public StringBuilder append(char[] str, int offset, int len) {
165 super.append(str, offset, len);
166 return this;
167 }
168
169 @Override
170 public StringBuilder append(boolean b) {
171 super.append(b);
172 return this;
173 }
174
175 @Override
176 public StringBuilder append(char c) {
177 super.append(c);
178 return this;
179 }
180
181 @Override
182 public StringBuilder append(int i) {
183 super.append(i);
184 return this;
185 }
186
187 @Override
188 public StringBuilder append(long lng) {
189 super.append(lng);
190 return this;
191 }
192
193 @Override
194 public StringBuilder append(float f) {
195 super.append(f);
196 return this;
197 }
198
199 @Override
200 public StringBuilder append(double d) {
201 super.append(d);
202 return this;
203 }
204
205 /**
206 * @since 1.5
207 */
208 @Override
209 public StringBuilder appendCodePoint(int codePoint) {
210 super.appendCodePoint(codePoint);
211 return this;
212 }
213
214 /**
215 * @throws StringIndexOutOfBoundsException {@inheritDoc}
216 */
217 @Override
218 public StringBuilder delete(int start, int end) {
219 super.delete(start, end);
220 return this;
221 }
222
223 /**
224 * @throws StringIndexOutOfBoundsException {@inheritDoc}
225 */
226 @Override
227 public StringBuilder deleteCharAt(int index) {
228 super.deleteCharAt(index);
229 return this;
230 }
231
232 /**
233 * @throws StringIndexOutOfBoundsException {@inheritDoc}
234 */
235 @Override
236 public StringBuilder replace(int start, int end, String str) {
237 super.replace(start, end, str);
238 return this;
239 }
240
241 /**
242 * @throws StringIndexOutOfBoundsException {@inheritDoc}
243 */
244 @Override
245 public StringBuilder insert(int index, char[] str, int offset,
246 int len)
247 {
248 super.insert(index, str, offset, len);
249 return this;
250 }
251
252 /**
253 * @throws StringIndexOutOfBoundsException {@inheritDoc}
254 */
255 @Override
256 public StringBuilder insert(int offset, Object obj) {
257 super.insert(offset, obj);
258 return this;
259 }
260
261 /**
262 * @throws StringIndexOutOfBoundsException {@inheritDoc}
263 */
264 @Override
265 public StringBuilder insert(int offset, String str) {
266 super.insert(offset, str);
267 return this;
268 }
269
270 /**
271 * @throws StringIndexOutOfBoundsException {@inheritDoc}
272 */
273 @Override
274 public StringBuilder insert(int offset, char[] str) {
275 super.insert(offset, str);
276 return this;
277 }
278
279 /**
280 * @throws IndexOutOfBoundsException {@inheritDoc}
281 */
282 @Override
283 public StringBuilder insert(int dstOffset, CharSequence s) {
284 super.insert(dstOffset, s);
285 return this;
286 }
287
288 /**
289 * @throws IndexOutOfBoundsException {@inheritDoc}
290 */
291 @Override
292 public StringBuilder insert(int dstOffset, CharSequence s,
293 int start, int end)
294 {
295 super.insert(dstOffset, s, start, end);
296 return this;
297 }
298
299 /**
300 * @throws StringIndexOutOfBoundsException {@inheritDoc}
301 */
302 @Override
303 public StringBuilder insert(int offset, boolean b) {
304 super.insert(offset, b);
305 return this;
306 }
307
308 /**
309 * @throws IndexOutOfBoundsException {@inheritDoc}
310 */
311 @Override
312 public StringBuilder insert(int offset, char c) {
313 super.insert(offset, c);
314 return this;
315 }
316
317 /**
318 * @throws StringIndexOutOfBoundsException {@inheritDoc}
319 */
320 @Override
321 public StringBuilder insert(int offset, int i) {
322 super.insert(offset, i);
323 return this;
324 }
325
326 /**
327 * @throws StringIndexOutOfBoundsException {@inheritDoc}
328 */
329 @Override
330 public StringBuilder insert(int offset, long l) {
331 super.insert(offset, l);
332 return this;
333 }
334
335 /**
336 * @throws StringIndexOutOfBoundsException {@inheritDoc}
337 */
338 @Override
339 public StringBuilder insert(int offset, float f) {
340 super.insert(offset, f);
341 return this;
342 }
343
344 /**
345 * @throws StringIndexOutOfBoundsException {@inheritDoc}
346 */
347 @Override
348 public StringBuilder insert(int offset, double d) {
349 super.insert(offset, d);
350 return this;
351 }
352
353 @Override
354 public int indexOf(String str) {
355 return super.indexOf(str);
356 }
357
358 @Override
359 public int indexOf(String str, int fromIndex) {
360 return super.indexOf(str, fromIndex);
361 }
362
363 @Override
364 public int lastIndexOf(String str) {
365 return super.lastIndexOf(str);
366 }
367
368 @Override
369 public int lastIndexOf(String str, int fromIndex) {
370 return super.lastIndexOf(str, fromIndex);
371 }
372
373 @Override
374 public StringBuilder reverse() {
375 super.reverse();
376 return this;
377 }
378
379 @Override
380 public String toString() {
381 // Create a copy, don't share the array
382 return new String(value, 0, count);
383 }
384
385 /**
386 * Save the state of the {@code StringBuilder} instance to a stream
387 * (that is, serialize it).
388 *
389 * @serialData the number of characters currently stored in the string
390 * builder ({@code int}), followed by the characters in the
391 * string builder ({@code char[]}). The length of the
392 * {@code char} array may be greater than the number of
393 * characters currently stored in the string builder, in which
394 * case extra characters are ignored.
395 */
396 private void writeObject(java.io.ObjectOutputStream s)
397 throws java.io.IOException {
398 s.defaultWriteObject();
399 s.writeInt(count);
400 s.writeObject(value);
401 }
402
403 /**
404 * readObject is called to restore the state of the StringBuffer from
405 * a stream.
406 */
407 private void readObject(java.io.ObjectInputStream s)
408 throws java.io.IOException, ClassNotFoundException {
409 s.defaultReadObject();
410 count = s.readInt();
411 value = (char[]) s.readObject();
412 }
413
414 }
2、常用方法
1、append(String str)/append(Char c):字符串连接
System.out.println("StringBuilder:"+strB.append("ch").append("111").append('c'));
//return "StringBuilder:ch111c"
2、toString():返回一个与构建起或缓冲器内容相同的字符串
System.out.println("String:"+strB.toString());
//return "String:ch111c"
3、appendcodePoint(int cp):追加一个代码点,并将其转换为一个或两个代码单元并返回this
System.out.println("StringBuilder.appendCodePoint:"+strB.appendCodePoint(2));
//return "StringBuilder.appendCodePoint:ch111c"
4、setCharAt(int i, char c):将第 i 个代码单元设置为 c(可以理解为替换)char字符使用 ‘ ’
strB.setCharAt(2, 'd');
System.out.println("StringBuilder.setCharAt:" + strB);
//return "StringBuilder.setCharAt:chd11c"
5、insert(int offset, String str)/insert(int offset, Char c):在指定位置之前插入字符(串)
System.out.println("StringBuilder.insertString:"+ strB.insert(2, "LS"));
//return "StringBuilder.insertString:chLSd11c"
System.out.println("StringBuilder.insertChar:"+ strB.insert(2, 'L'));
//return "StringBuilder.insertChar:chLLSd11c"
6、delete(int startIndex,int endIndex):删除起始位置(含)到结尾位置(不含)之间的字符串
System.out.println("StringBuilder.delete:"+ strB.delete(2, 4));
//return "StringBuilder.delete:chSd11c"
3、StringBuffer
和StringBulider用法差不多,不过多介绍,主要看一下三者的区别
解释:
String 类型和 StringBuffer 类型的主要性能区别其实在于 String 是不可变的对象, 因此在每次对 String 类型进行改变的时候其实都等同于生成了一个新的 String 对象,然后将指针指向新的 String 对象,所以 经常改变内容的字符串最好不要用 String ,因为每次生成对象都会对系统性能产生影响,特别当内存中无引用对象多了以后, JVM 的 GC 就会开始工作,那速度是一定会相当慢的。
而如果是使用 StringBuffer 类则结果就不一样了,每次结果都会对 StringBuffer 对象本身进行操作,而不是生成新的对象,再改变对象引用。所以在一般情况下我们推荐使用 StringBuffer ,特别是字符串对象经常改变的情况下。
为什么是大多数情况呢?
在某些特别情况下, String 对象的字符串拼接其实是被 JVM 解释成了 StringBuffer 对象的拼接, 所以这些时候 String 对象的速度并不会比 StringBuffer 对象慢,而特别是以下的字符串对象生成中, String 效率是远要比 StringBuffer 快的:
1 String S1 = “This is only a” + “ simple” + “ test”;
2 StringBuffer Sb = new StringBuilder(“This is only a”).append(“simple”).append(“ test”);
你会很惊讶的发现,生成 String S1 对象的速度简直太快了,而这个时候 StringBuffer 居然速度上根本 一点都不占优势。其实这是 JVM 的一个把戏,在 JVM 眼里,这个
String S1 = “This is only a” + “ simple” + “test”;
其实就是:String S1 = “This is only a simple test”;
所以当然不需要太多的时间了。但大家这里要注意的是,如果你的字符串是来自另外的 String 对象的话,速度就没那么快了,譬如:
String S2 = “This is only a”; String S3 = “ simple”; String S4 = “ test”;
大部分情况下StringBuilder的速度要大于StringBuffer:
java.lang.StringBuilder一个可变的字符序列是5.0新增的。(大多数情况下就是我们是在单线程下进行 的操作,所以大多数情况下是建议用StringBuilder而不用StringBuffer的)此类提供一个与 StringBuffer 兼容的 API,但不保证同步。该类被设计用作 StringBuffer 的一个简易替换,用在字符串缓冲区被单个 线程使用的时候(这种情况很普遍)。如果可能,建议优先采用该类,因为在大多数实现中,它比 StringBuffer 要快。两者的方法基本相同。
对于三者使用的总结:
1)如果要操作少量的数据用 = String
2)单线程操作字符串缓冲区下操作大量数据 = StringBuilder
3)多线程操作字符串缓冲区 下操作大量数据 = StringBuffer
File类
1、File类的基本用法
1. java.io.File类:文件和目录路径名的抽象表示形式。
File类的常见构造方法:
public File(String pathname)
以pathname为路径创建File对象,如果pathname是相对路径,则默认的当前路径在系统属性user.dir 中存储。
1. File的静态属性String separator存储了当前系统的路径分隔符。
2. 通过File对象可以访问文件的属性。
1 public boolean canRead()
2 public boolean exists()
3 public boolean isFile()
4 public long lastModified()
5 public String getName()
6 public boolean canWrite()
7 public boolean isDirectory()
8 public boolean isHidden()
9 public long length()
10 public String getPath()
1. 通过File对象创建空文件或目录(在该对象所指的文件或目录不存在的情况下)。
public boolean createNewFile()throws IOException
public boolean delete()
public boolean mkdir(), mkdirs()
1. 常见构造器,方法
【演示】
import java.io.File;
import java.io.IOException;
public class TestFile {
/**
* File文件类 1.代表文件 2.代表目录
*/
public static void main(String[] args) {
File f = new File("d:/src3/TestObject.java");
File f2 = new File("d:/src3");
File f3 = new File(f2, "TestFile.java");
File f4 = new File(f2, "TestFile666.java");
File f5 = new File("d:/src3/aa/bb/cc/dd");
//f5.mkdirs();
f5.delete();
try {
f4.createNewFile();
System.out.println("文件创建成功!");
} catch (IOException e) {
e.printStackTrace();
}
if (f.isFile()) {
System.out.println("是一个文件!");
}
if (f2.isDirectory()) {
System.out.println("是一个目录!");
}
if (f3.isFile()) {
System.out.println("是一个文件奥");
}
}
}