Java之常用类(二)

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("是一个文件奥");
        }
        }
}

 

posted @ 2021-03-07 15:57  |好的|  阅读(111)  评论(0编辑  收藏  举报