DAY14 StringBuffer类克隆

DAY21

一、StringBuffer和StringBuilder类

1、StringBuffer 类

​ 是一个字符串缓冲区的类,线程安全运行效率低,用户存储可变字符串

​ 构造器:

StringBuffer sb = new StringBuffer(); // 创建空字符串的容器
StringBuffer sb = new StringBuffer(String);// 将字符串使用容器存储
StringBuffer sb = new StringBuufer(int);//声明指定容量的容器


​    常用方法:

 1.1、append():追加字符串

1.2、delete(int start,int end):删除指定位置的字符

1.3、insert(int start ,String):插入到指定位置

1.4、reverse():反转字符

1.5、capacity():获取初始容量

1.6、ensureCapacity(int):设置最低所需容量

## 2、StringBuilder类

  也是字符串缓冲区的类,它是线程不安全,且运行效率高的可变字符串缓冲类

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RXK560hq-1603624328042)(file://C:/Users/Amry/Desktop/%E8%AF%BE%E5%A0%82%E7%AC%94%E8%AE%B0%20%20%E8%B5%84%E6%96%99/%E7%AC%94%E8%AE%B0/DAY21%20StringBuffer%20%E5%85%8B%E9%9A%86%20%E6%9E%9A%E4%B8%BE%20Math/assets/22.png?lastModify=1603280045)]

  其StringBuilder的方法与StringBuffer几乎一样

## 3、面试题

  1、StringBuffer、StringBuilder和String的区别

​       a、在运行速度上  : StringBuilder > StringBuffer  >  String 

​             原因: String是字符串常量,而StringBuilder和StringBuffer是字符串变量,当需要改变字符串内容时,Stirng重新创建变量并赋值, 而StringBuilder和StringBuffer可直接改原有的值,所有效率高,     

​           b、在线程安全上:   StringBuffer >  StringBuilder > String 

​           原因: StringBuffer是线程安全的,而StringBuilder线程不安全,在StringBuffer上的很多方法增加同步关键字(synchronized),导致在多个线程运行时,保持数据的完整性和一致性,而StringBuilder的方法并没有同步 ,如果在多线程环境下为了确保数据安全,建议使用StringBuffer ,如果在单线程环境下,提高效率使用StringBuilder。



## 二、对象的克隆

## 1、为什么需要克隆?

​     对于基本数据类型,可以将值直接复制给另一个变量,这里两个变量相互独立,而引用数据类型(自定义类) 对于引用类型的赋值并没有产生新的个体,而是将两个变量的类型指向同一个对象。 (本质只有一个对象),如果想要赋值的对象与原始对象独立,则需要进行“对象克隆”

## 2、如何克隆

​    我们知道任意一个类都继承自Object类,其中Object类提供一个clone方法 用于克隆对象。 

​    实现步骤: 

​     a、 实现 接口  Cloneable  

​     b、重写 clone方法(由于该方法是Object的 protectect修饰 不能直接访问)

## 3、浅克隆和深克隆

### 3.1、浅克隆

在浅克隆中,如果原型对象的成员变量是值类型,将复制一份给克隆对象;如果原型对象的成员变量是引用类型,则将引用对象的地址复制一份给克隆对象,也就是说原型对象和克隆对象的成员变量指向相同的内存地址。

   Java的对象克隆默认是浅克隆,

   [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-a3mseG5w-1603624328046)(file://C:/Users/Amry/Desktop/%E8%AF%BE%E5%A0%82%E7%AC%94%E8%AE%B0%20%20%E8%B5%84%E6%96%99/%E7%AC%94%E8%AE%B0/DAY21%20StringBuffer%20%E5%85%8B%E9%9A%86%20%E6%9E%9A%E4%B8%BE%20Math/assets/%E6%B5%85%E5%85%8B%E9%9A%86.png?lastModify=1603280045)]



### 3.2、深克隆

在深克隆中,无论原型对象的成员变量是值类型还是引用类型,都将复制一份给克隆对象,深克隆将原型对象的所有引用对象也复制一份给克隆对象。

简单来说,在深克隆中,除了对象本身被复制外,对象所包含的所有成员变量也将复制。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9H4dHOLn-1603624328051)(file://C:/Users/Amry/Desktop/%E8%AF%BE%E5%A0%82%E7%AC%94%E8%AE%B0%20%20%E8%B5%84%E6%96%99/%E7%AC%94%E8%AE%B0/DAY21%20StringBuffer%20%E5%85%8B%E9%9A%86%20%E6%9E%9A%E4%B8%BE%20Math/assets/%E6%B7%B1%E5%85%8B%E9%9A%86%20-1603252064551.png?lastModify=1603280045)]



实现深克隆的方式:

​     1、需要将克隆对象的引用数据类型 也实现克隆 














public class Student implements Cloneable {
private int id;
private String sname;
private int age;
//收货地址
private Address address;
//实现深克隆
@Override
protected Object clone() throws CloneNotSupportedException {
// return super.clone();
Student stu = (Student)super.clone();
// 获取学生的address
Address address = (Address) stu.getAddress().clone();
// 将address对象放入 新克隆的stu中
stu.setAddress(address);
return stu;

}

}

public class Address implements Cloneable{
//联系人
private String contectName;
//联系电话
private String contectPhone;
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}




测试:














public static void main(String[] args) throws CloneNotSupportedException {
// 创建学生对象
Student stu1 = new Student(1001,“马创”,22);
Address address = new Address(“马创的女朋友”,“18888888888”);
// 将收货地址 与该学生对象关联
stu1.setAddress(address);

    //克隆一个对象
    Student stu2 = (Student)stu1.clone();

    System.out.println(stu1.getId()+"---"+stu1.getSname());
    System.out.println(stu2.getId()+"---"+stu2.getSname());
   // 问题:是否会克隆新的address对象 还是说address的内存地址相同
    System.out.println(stu1.getAddress());
    System.out.println(stu2.getAddress());

    // 对于克隆对象的引用数据类型,它默认不会创建引用数据类型的 新对象
    //  这种方式称为“浅克隆”

    // Java也可以实现深克隆
    System.out.println(stu1.getAddress().getContectName());
    System.out.println(stu2.getAddress().getContectName());
}



结果:

1001---马创 1001---马创 com.j2008.clones.Address@4554617c com.j2008.clones.Address@74a14482 马创的女朋友 马创的女朋友



## 三、枚举类(enum)

## 1、枚举类型的诞生

​       在JDK5以前,定义常量需要使用public fiinal  static..  单独定义,如果有一组常量,需要定义一组final修饰的类型。这样会很繁琐,JDK5以后推出枚举类型。 可以将一组常量定义一个自定义类,使用是通过该类型直接方法。  

## 2、 枚举类型的语法

​     














public enum 枚举类型名称{
值1,值2,值3…
}
访问时: 枚举类型名称.值1




用法1:














public enum Color {
RED(),YELLOW(),BLUE();

}
public static boolean isRedColor(Color color){
if(color.equals(Color.RED)){
return true;
}
return false;
}

public static void main(String[] args) {
System.out.println(isRedColor(Color.BLUE));
System.out.println(isRedColor(Color.RED));
}




用法2: 定义枚举类的属性 并赋值














public enum PROVINCES {
//枚举的值 在初始化枚举值时,通过构造器给它的属性赋值
HB(“湖北”,0),BJ(“北京”,1),HN(“湖南”,2),FJ(“福建”,3);

//枚举的属性
private String provinceName;
private int index;
//枚举的构造器
private PROVINCES(String provinceName,int index){
    this.provinceName= provinceName;
    this.index = index;
}

public String getProvinceName() {
    return provinceName;
}

public void setProvinceName(String provinceName) {
    this.provinceName = provinceName;
}

public int getIndex() {
    return index;
}

public void setIndex(int index) {
    this.index = index;
}

}



















//输出某一枚举的值 name和 index
System.out.println(PROVINCES.BJ.getProvinceName());
System.out.println(PROVINCES.BJ.getIndex());

    //遍历所有的枚举的值
     PROVINCES [] provs = PROVINCES.values();
    for(PROVINCES pro :  provs){
        System.out.println(pro.getIndex()+"---"+pro.getProvinceName());
    }







## 四、Math类

   java.lang.Math类用于数学计算的工具类 ,它提供都是静态方法  ,不需要构造Math对象

常用方法:

​     Math.random():获取随机数

​    Math.abs() 获取绝对值

​    Math.ceil(): 向上取整

   Math.floor() :向下取整

   Math.rint():取接近它的整数 ,如果两个同样接近,往偶数靠近

  Math.max(int,int):返回两个数的最大值

  Math.min(int,int):返回两个数的最小值

 Math.round():四舍五入整数

 Math .sqrt():对一个数开平方

 Math.pow(double,double),对一个数的几次幂














public static void main(String[] args) {
System.out.println(Math.PI);
System.out.println(Math.E);
System.out.println(" 一个数的绝对值:"+Math.abs(-100));//100
System.out.println(" 向上取整:"+Math.ceil(13.5)); // 14
System.out.println(" 向上取整(比它大的最近数):"+Math.ceil(-13.5));// -13
System.out.println(“向下取整:”+ Math.floor(13.5));// 13
System.out.println(“向下取整”+Math.floor(-20.2));// -21

    //四舍五入
    System.out.println(Math.round(23.4));// 23
    System.out.println(Math.round(-23.5));//-23
    System.out.println(Math.round(-24.5));//-24

    System.out.println(Math.rint(23.4));// 23
    System.out.println(Math.rint(23.5));//24 如果两个一样接近,取接近偶数
    System.out.println(Math.rint(22.5));//22
    System.out.println(Math.rint(0.6));//0

}





  

## 五、大数据类型BigDecimal

1、BigDecimal类

  两个double类型的计算可能导致精度不准确,这里使用

java.math.*里面提供了BigDecimal类(提供高精度计算的方法)














public static void main(String[] args) {
double a= 1.200000;
double b= 1.35433;
double c = a+b;
System.out.println©;
System.out.println(0.05+0.01);
System.out.println(1.0-0.42); // 会出现精度问题 计算不准确

    // 使用BigDecimal ,先将类型转成字符串 (为了避免精度问题)
    BigDecimal num1 = new BigDecimal("0.051");
    BigDecimal num2 = new BigDecimal("0.012");
    // 两个数相加

    BigDecimal sum = num1.add(num2 ) ;
    // 设置保留2位整数  四舍五入
    sum =sum.setScale(2,BigDecimal.ROUND_HALF_UP);
    System.out.println(sum);

    // 减法
   sum =  num1.subtract(num2);
    System.out.println(sum);

   // 乘法
   sum =  num1.multiply(num2);
    System.out.println(sum);

   // 除法
   sum = num1.divide(num2,2,BigDecimal.ROUND_HALF_UP);
    System.out.println(sum);

}



## 2、NumberFormat类

java.text.NumberFormat类 :用于将数值格式转成指定格式并输出字符串形式的类 。 

DecimalFormat类: 属于NumberFormat的子类。 










// NumberFormat类是对数值类型的格式化类,其中 DecimalFormat是继承NumberFormat
// 获取数值的货币表现形式
NumberFormat nf = NumberFormat.getCurrencyInstance();
String s1 = nf.format(23424.2);
System.out.println(s1);

    //获取数值的百分比
    nf = NumberFormat.getPercentInstance();
    s1= nf.format(0.654);
    System.out.println(s1);

    //根据指定的格式匹配百分比
    nf = new DecimalFormat("##.##%");
    s1=nf.format(0.654);
    System.out.println(s1);

    // 根据指定的模式匹配千分比
    nf = new DecimalFormat("##.##\u2030");
    s1 = nf.format(0.6543);
    System.out.println(s1);

    // 根据指定的模式 转成科学计数法
    nf = new DecimalFormat("#.###E0");
    s1 = nf.format(198200);
    System.out.println(s1);

    // 根据指定的模式  将字符串转成 指定格式数值型
    String s2 ="25.3%";
    nf = new DecimalFormat("##.##%");
    Number dd = nf.parse(s2);
    double num = (double)dd;
    System.out.println("这个字符串转成double:"+num);





题目: 控制台输入 n个学生 的分数 , 60分以上的是及格,85分以上的是优秀,问学生的及格率是多少,优秀率是多少,使用百分比表示。、
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值