Java学习-Day18(包装类、String类、Math类、Arrays类)

常用类

包装类(Wrapper)

  • 分类

    1. 针对霸总基本数据类型相应的引用类型——包装类
    2. 有了类的特点,就可以调用类中的方法
    基本数据类型包装类
    booleanBoolean
    charCharacter
    byteByte
    intInteger
    longLong
    floatFloat
    doubleDouble
    shortShort

    Byte…Short,他们的父类都是Number

  • 包装类和基本数据类型的转换

    1. jdk5之前手动装箱和拆箱方式

       int n = 100;
      
      //jdk5之前手动装箱
      Integer integer = new Integer(n);
      Integer valueOf = Integer.valueOf(n);
      
      //手动拆箱
      int m = integer.intValue();
      
    2. jdk5及之后是自动装箱和拆箱方式

       //jdk5及之后自动装箱
      int a = 100;
      Integer integer = a;//底层还是 Integer.valueOf(a)
              
      //自动拆箱
      int b = integer;//底层使用的还是integer.intValue()
      
    3. 其他包装类的使用方法与int相同

  • 三元运算符要看做一个整体,有int和double,精度按double来

  • 包装类和String相互转换

    Integer integer = 100;//自动装箱
    //Integer和String互相转换
    //Integer=>String
    //方式1
    String s1 = integer + "";
    //方式2
    String s2 = integer.toString();
    //方式3
    String s3 = String.valueOf(integer);
    
    //String=>Integer
    String str = "123";
    //方式1
    Integer i1 = Integer.parseInt(str);
    //方式2
    Integer i2 = new Integer(str);
    
  • Integer和Char包装类的常用方法
    在这里插入图片描述

  • Integer m = 1;
    Integer n = 1;
    System.out.println(m == n);//T
    //当m和n在-128-127之间时,直接返回一个Integer对象,所以m和n是同一个对象,当不在次范围内时,就要new一个Integer,m和n就是两个对象了
    
  • 只要有基本数据类型,==判断的是二者值是否相等

String类

  • String的理解和创建对象

    1. String对象用于保存字符串,也就是一组字符序列

    2. 字符串常量对象是用双引号括起的字符序列,String str = “ak47”; "ak47"就是常量,str是变量

    3. String使用的是Unicode编码,一个字符(不区分字母还是汉字)占两个字节

    4. String类的常用构造器

      String s1 = new String();
      String s2 = new String(String origianl);
      String s3 = new String(char[] a);
      String s4 = new String(char[],int startIndex,int count);
      String s5 = new String(byte[] b);
      
    5. String类实现了Serializable接口,说明String可串行化,可以在网络传输

    6. String 类实现了Comparable接口,说明String对象可以比较,compareTo()方法

    7. String是final类,不能被其他类继承

    8. String有属性private final char value[],用于存放字符串内容,value是一个final类型,不可以修改(内容可改,地址不可修改=>也就是不能让value再指向其他的对象)

  • 创建String对象的两种方式

    1. 直接赋值 String s = “aaaaa”;

      先从常量池查看是否有“aaaaa“的数据,如果有,直接指向,如果没有则重新创建再指向。最终s指向的是常量池的空间地址。

    2. 调用构造器String s = new String(“aaaaa”)

      先在堆中创建空间,里面维护了value属性,指向常量池的“aaaaa‘空间,如果常量池没有则重新创建,如果有则直接通过value指向,最终s指向的是堆中的空间地址,value指向的是常量池的地址

  • intern方法

    最终返回的是常量池中字符串的地址

  • 字符串的特性

    1. String是一个final类,代表不可变的字符序列

    2. 字符串是不可变的。一个字符串对象一旦被分配,其内容是不可变的。

    3. String s1 = "Hello";
      s1 = "haha";
      //创建了两个对象,先看常量池中有没有"haha",如果有s1直接指向,如果没有就新建一个"haha"再指向,并没有改变"Hello"
      
      String a = "hello" + "abc";
      //编译器会优化,等价于String a = "helloabc"; 所以只创建了一个对象。编译器判断创建的常量池对象是否有引用指向,没有的话肯定说明没人用,创建一个最终的就可以了。
      
      String a = "hello";//创建a对象
      String b = "abc";//创建b对象
      String c = a + b;
      //1、先创建一个StringBuffer
      //2、执行sb.append("hello")
      //3、执行sb.append("abc")
      //4、执行String c =  sb.toString()
      //其实最后是c指向堆中的对象(String) value[] ->常量池中的"helloabc"
      
      String c1 = "ab" + "cd";
      //常量相加,看的是池
      String c1 = a + b;
      //变量相加,是在堆中
      
  • String类的常见方法

    String类是保存字符串常量的,每次更新都需要开辟空间,效率较低

    equals() //区分大小写,判断内容是否相等
    equalslgnoreCase()//忽略大小写的判断内容是否相等
    length()//获取字符的个数,字符串的长度
    indexOf()//获取字符在字符串中第1次出现的索引,索引从0开始,如果找不到,返回-1,参数可以是字符也可以是字符串
    lastIndexOf()//获取字符在字符串中最后1次出现的索引,索引从0开始,如找不到,返回-1
    substring()//截取指定范围的子串
    //(6):从索引6开始,截取后面所有的内容
    //(0,5):从索引0开始截取,截取到索引为5-1=4的字符
    trim//去前后空格
    charAt()//获取某索引处的字符,注意不能使用Str[index] 这种方式;
        
        
    toUpperCase()//转大写
    toLowerCase()//转小写
    concat()//拼接
    replace("","")//替换字符串中的字符,s2 = s1.replace,s1没有变化,s2是替换后的内容
    split()//分割字符串,对于某些分割字符,我们需要转义比如| \\等,split(",")指把字符串按逗号分割,返回字符串数组;在对字符串进行分割时,如果有特殊字符,需要加转义字符\
    compareTo()//比较两个字符串的大小,如果前者大返回正数,如果后者大返回负数,相等返回0;返回第一个不同的字符的差,如果长度不等,其中一个字符串是另一个的字串,则返回长度差
    //1、如果长度相同,每个字符也相同,返回0
    //2、如果长度相同或不相同,但是在进行比较时可以区分大小,返回第一个不同的字符的差
    //3、如果长度不等,其中一个字符串是另一个的字串,则返回长度差
    toCharArray()//转换成字符数组
    format()//格式字符串,占位符如下:
    //%s字符串	%c字符	%d整型	%.2f浮点型
    //占位符由后面的变量替换
    
    

StringBuffer类

  • 基本介绍

    1. java.lang.StringBuffer代表可变的字符序列,可以对字符串内容进行增删
    2. 很多方法与String相同,但是StringBuffer是可变长度的
    3. StringBuffer是一个容器
    4. StringBuffer的直接父类是AbstractStringBuffer
    5. StringBuffer实现了Serializable,即StringBuffer的对象可以串行化
    6. 在父类中,AbstractStringBuffer有属性char[] value,不是final,value数组存放字符串内容,引出存放在堆中的
    7. StringBuffer是一个final类,不能被继承
  • String VS StringBuffer

    1. String保存的是字符串常量,里面的值不能更改,每次String类的更新实际上就是更改地址,效率较低

    2. StringBuffer保存的是字符串变量,里面的值可以更改,每次StringBuffer的更新实际上可以更新内容,不用每次更新地址,效率较高

      //char[] value; //这个放在堆

    3. 因为StringBuffer的字符序列是存放在char [] value,所以变化时不用每次都更换地址(即不是每次都创建新对象)所以效率高于String

  • StringBuffer的构造器

    • StringBuffer( ) // 创建一个大小为16的char[],用于存放
    • StringBuffer(CharSequence seq) //构造一个字符串缓冲区,它包含与指定的CharSequence相同的字符
    • StringBuffer(int capacity) //capacity 容量 构造一个不带字符但具有初始容量的字符串缓冲区,即对char[]大小进行指定
    • StringBuffer(String str) //构造一个字符串缓冲区,并将其内容初始化为指定的字符串内容(char[]数组长度增加了16)
  • String与StringBuffer互相转换

    1. String==>StringBuffer

      String str = "a";
      //方式一,使用构造器
      //返回的是StringBuffer对象,对str没有任何影响
      StringBuffer str1 = new StringBuffer("str");
      
      //方式二 使用append()方法
      StringBuffer stringBuffer = new StringBuffer();
      stringBuffer.append(str);
      
    2. StringBuffer==>String

      //方式一 使用toString方法
      StringBuffer strb = new StringBuffer("a");
      String strstr = strb.toString();
      
      //方式二,使用构造器
      String str2 = new String(strb);
      //strb为空时会报空指针异常,因为源码需要用到strb.length()
      
  • StringBuffer常用方法

    1. append()–增加,如果参数为空,调用appendNull方法,StringBuffer内容为“null”
    2. delete(11,14)–删除11-14的字符,[11,14),包含11不含14
    3. replace(9,11,“a”)–使用a替换9-11的字符[9-11),包含9不包含11
    4. indexOf(“qaq”)–查找指定的字串在字符串中第一次出现的索引,如果找不到返回-1
    5. insert(9,“ak”)–在索引为9的位置插入ak,原来索引为9的内容自动后移
    6. length()–返回长度

StringBuilder类

  • 基本介绍

    1. 一个可变的字符序列。此类提供一个与StringBuffer兼容的API,但不保证同步(StringBuilder不是线程安全)。该类被设计用作 StringBuffer的一个简易替换,用在字符串缓冲区被单个线程使用的时候如果可能,建议优先采用该类,因为在大多数实现中,它比 StringBuffer 要快。
    2. 在StringBuilder上的主要操作是append和 insert方法,可重载这些方法,以接受任意类型的数据。
  • 常用方法

    与StringBuffer方法一样

    1. StringBuilder继承 AbstractStringBuilder类
    2. 实现了Serializable ,,说明StringBuilder对象是可以串行化(对象可以网络传输,可以保存到文件)
    3. StringBuilder是final类,不能被继承
    4. StringBuilder对象字符序列,仍然是存放在其父类 AbstractStringBuilder的 char[] value;因此,字符序列是堆中
    5. StringBuilder 的方法,没有做互斥的处理,即没有synchronized关键字,因此在单线程情况下使用
  • String vs StringBuffer vs StringBuilder

    1. StringBuilder 和 StringBuffer非常类似,均代表可变的字符序列,而且方法也一样

    2. String:不可变字符序列,效率低,但是复用率高(一个常量池的字符串可以有多个引用)。

    3. StringBuffer:可变字符序列、效率较高(增删)、线程安全(有synchronized关键字,同步的意思)

    4. StringBuilder:可变字符序列、效率最高、线程不安全

    5. String使用注意说明:

      String s = "a";//创建了一个字符串
      s += "b";//实际上原来的"a"字符串对象已经丢弃了,现在又产生了一个字符串s+"b”(也就是"ab")。
      //如果多次执行这些改变串内容的操作,会导致大量副本字符串对象存留在内存中,降低效率。如果这样的操作放到循环中,会极大影响程序的性能=>
      //结论:如果我们对String 做大量修改,不要使用String,用StringBuffer
      
    6. 效率测试

      StringBuilder > StringBuffer > String

  • String、StringBuffer、StringBuilder使用原则

    1.如果字符串存在大量的修改操作,一般使用 StringBuffer 或StringBuilder

    2.如果字符串存在大量的修改操作,并在单线程的情况,使用StringBuilder

    3.如果字符串存在大量的修改操作,并在多线程的情况,使用 StringBuffer

    4、如果我们字符串很少修改,多个对象引用,使用String, 比如配置信息等

Math类

常见的方法(静态)

  1. abs绝对值

  2. pow求幂

  3. ceil向上取整,返回大于等于该参数的最小整数(转成double)

  4. floor向下取整,返回小于等于该参数的最大整数(转成double)

  5. round四舍五入 相当于Math.floor(参数+0.5)

  6. sqrt求开方,参数为负返回NaN

  7. random求随机数 返回的是0 <= x < 1之间的随机小数

//返回a-b之间的整数,a<=x<=b
//int num = (int) (a + Math.random() * (b - a + 1))
  1. max求两个数的最大值

  2. min求两个数的最小值

Arrays类

包含一系列静态方法,用于管理或操作数组(比如排序和搜索)

  1. toString—返回数组的字符串形式

    //int[] arr = { 1,2,3 };
    //System.out.println(Arrays.toString(arr));
    //输出[1,2,3]
    
  2. sort 排序(自然排序和定制排序)

Integer arr[] = {1,-1,7,0,89,3};
//可以自己写冒泡,也可以用Arrays的sort(),从小到大
//因为数组是引用类型,所以通过sort排序后会直接影响到实参
//sort方法重载,也可以通过传入一个接口Comparator实现定制排序
//调用定制排序时,传入两个参数,一是排序的数组,二是实现了Comparator接口的匿名内部类,要求实现compare方法
//这里体现了接口编程的方式,在binarySort方法底层,会通过匿名内部类的compare方法来决定排序的顺序
Arrays.sort(arr, new Comparator() {
@Override
public int compare(Object o1, Object o2) {
Integer i1 = (Integer) o1;
Integer i2 = (Integer) o2;
return i2 - i1;
}
});
//源码分析:
/*
(1) Arrays.sort(arr, new Comparator()
(2) 最终到 TimSort 类的 private static <T> void binarySort(T[] a, int lo, int hi, int start,
Comparator<? super T> c)()
(3) 执行到 binarySort 方法的代码, 会根据动态绑定机制 c.compare()执行我们传入的匿名内部类的 compare ()
// while (left < right) {
// int mid = (left + right) >>> 1;
// if (c.compare(pivot, a[mid]) < 0)
// right = mid;
// else
// left = mid + 1;
// }
//(4) new Comparator() {
// @Override
// public int compare(Object o1, Object o2) {
// Integer i1 = (Integer) o1;
// Integer i2 = (Integer) o2;
// return i2 - i1;
// }
// }
//(5) public int compare(Object o1, Object o2) 返回的值>0 还是 <0会影响整个排序结果, 这就充分体现了 接口编程+动态绑定+匿名内部类的综合使用.将来的底层框架和源码的使用方式, 会非常常见
*/
  1. binarySearch — 通过二分搜索法进行查找,要求必须排好序
int index = Arrays.binarySearch(arr,3);
/*
1、使用binarySearch通过二分搜索法进行查找,要求必须有序,无序不能用
2、如果数组中不存在该元素,返回应插入的位置+1的相反数,存在返回索引
*/
  1. copyOf 数组元素的复制
Integer[] newArr = Arrays.copyOf(arr,arr.length);
/*
1. 从 arr 数组中, 拷贝 arr.length 个元素到 newArr 数组中
2. 如果拷贝的长度 > arr.length 就在新数组的后面 增加 null
3. 如果拷贝长度 < 0 就抛出异常 NegativeArraySizeException
4. 该方法的底层使用的是 System.arraycopy()
*/
  1. fill数组元素的填充
lnteger[]num = new Integer[]{9,3,23};
Arrays.fill(num, 99);
//使用 99 去填充 num 数组, 可以理解成是替换原来所有的元素
//num 变成 99 99 99
  1. equals比较两个数组元素内容是否完全一致,不是地址
boolean equals = Arrays.equals(arr,arr2);
//1. 如果 arr 和 arr2 数组的元素一样, 则方法 true;
//2. 如果不是完全一样, 就返回 false
  1. asList 将一组值,转换成list
List<Integer> asList = Arrays.asList(2,3,4,5,6,1);
System.out.println("asList=" + asList);
//1. asList 方法, 会将 (2,3,4,5,6,1)数据转成一个 List 集合
//2. 返回的 asList 编译类型 List(接口)
//3. asList 运行类型 java.util.Arrays#ArrayList, 是 Arrays 类的
// 静态内部类 private static class ArrayList<E> extends AbstractList<E>
// implements RandomAccess, java.io.Serializable

作业

import java.util.Arrays;
import java.util.Comparator;

/**
 * @author CUI
 * @version 1.0
 */
public class ArraysExercise {
    public static void main(String[] args) {
        Book[] books = new Book[4];
        books[0] = new Book("红楼梦", 100);
        books[1] = new Book("金瓶梅", 90);
        books[2] = new Book("青年文摘", 5);
        books[3] = new Book("java从入门到放弃", 300);

//        Book temp = null;
//        for (int i = 0; i < 4; i++) {
//            for (int j = 0; j < books.length - i - 1; j++) {
//                 if(books[j + 1].getPrice() > books[j].getPrice()){
//                     temp = books[j + 1];
//                     books[j + 1] = books[j];
//                     books[j] = temp;
//                 }
//            }
//        }
//        for(Book b : books){
//            System.out.println(b.getName()+ " " + b.getPrice());
//        }
//
//        System.out.println("==========================");
//
//        for (int i = 0; i < 4; i++) {
//            for (int j = 0; j < books.length - i - 1; j++) {
//                if(books[j + 1].getName().length() > books[j].getName().length()){
//                    temp = books[j + 1];
//                    books[j + 1] = books[j];
//                    books[j] = temp;
//                }
//            }
//        }
//
//        for(Book b : books){
//            System.out.println(b.getName()+ " " + b.getPrice());
//        }

        Arrays.sort(books, new Comparator<Book>() {
            @Override
            public int compare(Book o1, Book o2) {
                double difference = o1.getPrice() - o2.getPrice();
                if (difference > 0) {
                    return -1;
                } else if (difference < 0) {
                    return 1;
                } else {
                    return 0;
                }
            }
        });
        for (Book b : books) {
            System.out.println(b.getName() + " " + b.getPrice());
        }

    }
}

class Book {
    private String name;
    private double price;

    public Book(String name, double price) {
        this.name = name;
        this.price = price;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public double getPrice() {
        return price;
    }

    public void setPrice(double price) {
        this.price = price;
    }
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

晚来舟Mango

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值