Java入门(9)Java API

 String,StringBuilder,StringBuffer三者的区别

1.首先说运行速度,或者说是执行速度

  在这方面运行速度快慢为:StringBuilder > StringBuffer > String

  String最慢的原因:

  String的值是不可变的,这就导致每次对String的操作都会生成新的String对象,这样不仅效率低下,而且大量浪费有限的内存空间。

  

  String为字符串常量,而StringBuilder和StringBuffer均为字符串变量,即String对象一旦创建之后该对象是不可更改的,但后两者的对象是变量,是可以更改的。

2. 再来说线程安全

  StringBuilder 类在 Java 5 中被提出,它和 StringBuffer 之间的最大不同在于 StringBuilder 的方法不是线程安全的(不能同步访问)。

  由于 StringBuilder 相较于 StringBuffer 有速度优势,所以多数情况下建议使用 StringBuilder 类。然而在应用程序要求线程安全的情况下,则必须使用 StringBuffer 类。

3. 总结一下

  

  String:适用于少量的字符串操作的情况

  StringBuilder:适用于单线程下在字符缓冲区进行大量操作的情况

  StringBuffer:适用多线程下在字符缓冲区进行大量操作的情况

一、String

  String类的常见操作

 

特别要注意的是,String类的所有方法都没有改变字符串本身的值,都是返回了一个新的对象。

字符串常量池

String cmower = "沉默王二";
String cmower1 = "沉默王二";
System.out.println(cmower == cmower1); // 输出true
 
String cmowsan new String("沉默王三");
String cmowsan1 new String("沉默王三");
System.out.println(cmowsan == cmowsan1); // 输出false

双引号创建的相同字符串使用==判断时结果为true,而new关键字创建的相同字符串使用==判断时结果为false。

这是为什么呢?

String在Java中使用过于频繁,为了避免在系统中产生大量的String对象,Java的设计者引入了“字符串常量池”的概念。

当使用双引号创建一个字符串时,首先会检查字符串常量池中是否有相同的字符串对象,如果有,则直接从常量池中取出对象引用;如果没有,则新建字符串对象,并将其放入字符串常量池中,并返回对象引用。

这也就是说,"沉默王二"是放在字符串常量池中的,cmower和cmower1两个字符串对象引用是相同的。

而new关键字创建的字符串对象是不涉及字符串常量池的,直接放在堆中,也就是说,虽然cmowsan和cmowsan1都叫沉默王三,但不一个人。

强烈建议:不要使用new关键字的形式创建字符串对象。

二、StringBuffer

 三、StringBuilder

由于字符串是不可变的,因此字符串在进行拼接的时候会创建新的字符串对象。大家都知道,内存是一定的,因此对象创建多了就会影响系统性能。

StringBuilder正是为了解决字符串拼接产生太多中间对象的问题而提供的一个类,可以通过append()方法把字符串添加到已有序列的末尾,非常高效。
强烈建议:如果只是三四个字符串的拼接,尽管使用+号操作符,别想什么性能优化(举个例子,你离目的地只有100米,你是打算打个出租车,还是自己步行走过去?);如果遇到多于四个字符串的拼接,或者需要用到循环来拼接,那就选择StringBuilder。

关于StringUtils

字符串的操作往往需要用到一个工具类,那就是org.apache.commons.lang3.StringUtils(null安全的,也就是说,StringUtils类的方法可以接受为null的字符串,但不会抛出NullPointerException)。

 System类

 Runtime

Math

Random

包装类

  可以将基本数据类型的值包装为引用数据类型的对象。

 

 

Date、Calendar、DateFormat

Date类

  在java.util包中定义了Date类,Date类本身使用非常简单,直接输出其实例化对象即可。
import java.util.Date ;
public class DateDemo01{
    public static void main(String args[]){
        Date date = new Date() ;    // 直接实例化Date对象
        System.out.println("当前日期为:" + date) ;
    }
};

Calendar(弥补Date类的设计缺陷)

import java.util.* ;
public class DateDemo02{
    public static void main(String args[]){
        Calendar calendar = new GregorianCalendar();    // 实例化Calendar类对象
        System.out.println("YEAR: " + calendar.get(Calendar.YEAR));
        System.out.println("MONTH: " + (calendar.get(Calendar.MONTH) + 1));
        System.out.println("DAY_OF_MONTH: " + calendar.get(Calendar.DAY_OF_MONTH));
        System.out.println("HOUR_OF_DAY: " + calendar.get(Calendar.HOUR_OF_DAY));
        System.out.println("MINUTE: " + calendar.get(Calendar.MINUTE));
        System.out.println("SECOND: " + calendar.get(Calendar.SECOND));
        System.out.println("MILLISECOND: " + calendar.get(Calendar.MILLISECOND));
    }
};

DateFormat类

import java.text.DateFormat ;
import java.util.Date ;
public class DateDemo03{
    public static void main(String args[]){
        DateFormat df1 = null ;        // 声明一个DateFormat
        DateFormat df2 = null ;        // 声明一个DateFormat
        df1 = DateFormat.getDateInstance() ;    // 得到日期的DateFormat对象
        df2 = DateFormat.getDateTimeInstance() ;    // 得到日期时间的DateFormat对象
        System.out.println("DATE:" + df1.format(new Date())) ; // 按照日期格式化
        System.out.println("DATETIME:" + df2.format(new Date())) ;     // 按照日期时间格式化
 
    }
}
import java.text.DateFormat ;
import java.util.Date ;
import java.util.Locale ;
public class DateDemo04{
    public static void main(String args[]){
        DateFormat df1 = null ;        // 声明一个DateFormat
        DateFormat df2 = null ;        // 声明一个DateFormat
        df1 = DateFormat.getDateInstance(DateFormat.YEAR_FIELD,new Locale("zh","CN")) ;    // 得到日期的DateFormat对象
        df2 = DateFormat.getDateTimeInstance(DateFormat.YEAR_FIELD,DateFormat.ERA_FIELD,new Locale("zh","CN")) ;    // 得到日期时间的DateFormat对象
        System.out.println("DATE:" + df1.format(new Date())) ; // 按照日期格式化
        System.out.println("DATETIME:" + df2.format(new Date())) ;     // 按照日期时间格式化
 
    }
};

SimpleDateFormat类

import java.text.* ;
import java.util.* ;
public class DateDemo05{
    public static void main(String args[]){
        String strDate = "2008-10-19 10:11:30.345" ;
        // 准备第一个模板,从字符串中提取出日期数字
        String pat1 = "yyyy-MM-dd HH:mm:ss.SSS" ;
        // 准备第二个模板,将提取后的日期数字变为指定的格式
        String pat2 = "yyyy年MM月dd日 HH时mm分ss秒SSS毫秒" ;
        SimpleDateFormat sdf1 = new SimpleDateFormat(pat1) ;        // 实例化模板对象
        SimpleDateFormat sdf2 = new SimpleDateFormat(pat2) ;        // 实例化模板对象
        Date d = null ;
        try{
            d = sdf1.parse(strDate) ;    // 将给定的字符串中的日期提取出来
        }catch(Exception e){            // 如果提供的字符串格式有错误,则进行异常处理
            e.printStackTrace() ;        // 打印异常信息
        }
        System.out.println(sdf2.format(d)) ;    // 将日期变为新的格式
    }
};

Equals和==的区别

关于变量之间的比较,可以分为基础类型变量的比较和对象之间的比较。

对于基本类型来说,他们存储在jvm的栈中,因此比较的是变量的内容,也就是比较的变量的值。

对于引用类型来说,因为对象内容存储在jvm的堆中栈中只是存储对象的引用(地址),无论是==还是equals比较的都是栈中的内容,即对象的引用,也就是比较的是两个对象的地址。

但根据创建对象的方式不同可以分为两种情况:

 1. 使用表达式创建对象:

2.使用new方法创建对象:

这里会引入两个新的问题:

1.为什么表达式创建和new创建,会让==比较产生不同的结果。

这是因为jvm在程序运行的时候会创建一个缓冲池,当使用表达式创建的时候,程序会在缓冲池中寻找相同值的对象,如果找到,就把这个对象的地址赋给当前创 建的对象,因此,c和d实际上都指向了c的引用。因此在使用==时会返回true。

当用new创建对象时,是在堆中重新分配内存,因此栈中的引用是不相同的,所以,a和b引用的是值相同的不同对象。所以a==b返回false

2.既然equals比较的是引用,那么a.equals(b)为什么返回true。这是因为在Integer里,重写了equals方法!

资料

https://mp.weixin.qq.com/s/hiIBQu6mAPzYa7QgTNacUA

https://www.cnblogs.com/wupeixuan/p/8908524.html

http://www.cnblogs.com/guoyaohua/category/1149306.html

http://www.cnblogs.com/wtzbk/p/8591559.html

原文地址:https://www.cnblogs.com/cnki/p/9358165.html