常用类
包装类(Wrapper)
-  分类 - 针对霸总基本数据类型相应的引用类型——包装类
- 有了类的特点,就可以调用类中的方法
 基本数据类型 包装类 boolean Boolean char Character byte Byte int Integer long Long float Float double Double short Short Byte…Short,他们的父类都是Number 
-  包装类和基本数据类型的转换 -  jdk5之前手动装箱和拆箱方式 int n = 100; //jdk5之前手动装箱 Integer integer = new Integer(n); Integer valueOf = Integer.valueOf(n); //手动拆箱 int m = integer.intValue();
-  jdk5及之后是自动装箱和拆箱方式 //jdk5及之后自动装箱 int a = 100; Integer integer = a;//底层还是 Integer.valueOf(a) //自动拆箱 int b = integer;//底层使用的还是integer.intValue()
-  其他包装类的使用方法与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的理解和创建对象 -  String对象用于保存字符串,也就是一组字符序列 
-  字符串常量对象是用双引号括起的字符序列,String str = “ak47”; "ak47"就是常量,str是变量 
-  String使用的是Unicode编码,一个字符(不区分字母还是汉字)占两个字节 
-  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);
-  String类实现了Serializable接口,说明String可串行化,可以在网络传输 
-  String 类实现了Comparable接口,说明String对象可以比较,compareTo()方法 
-  String是final类,不能被其他类继承 
-  String有属性private final char value[],用于存放字符串内容,value是一个final类型,不可以修改(内容可改,地址不可修改=>也就是不能让value再指向其他的对象) 
 
-  
-  创建String对象的两种方式 -  直接赋值 String s = “aaaaa”; 先从常量池查看是否有“aaaaa“的数据,如果有,直接指向,如果没有则重新创建再指向。最终s指向的是常量池的空间地址。 
-  调用构造器String s = new String(“aaaaa”) 先在堆中创建空间,里面维护了value属性,指向常量池的“aaaaa‘空间,如果常量池没有则重新创建,如果有则直接通过value指向,最终s指向的是堆中的空间地址,value指向的是常量池的地址 
 
-  
-  intern方法 最终返回的是常量池中字符串的地址 
-  字符串的特性 -  String是一个final类,代表不可变的字符序列 
-  字符串是不可变的。一个字符串对象一旦被分配,其内容是不可变的。 
-  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类
-  基本介绍 - java.lang.StringBuffer代表可变的字符序列,可以对字符串内容进行增删
- 很多方法与String相同,但是StringBuffer是可变长度的
- StringBuffer是一个容器
- StringBuffer的直接父类是AbstractStringBuffer
- StringBuffer实现了Serializable,即StringBuffer的对象可以串行化
- 在父类中,AbstractStringBuffer有属性char[] value,不是final,value数组存放字符串内容,引出存放在堆中的
- StringBuffer是一个final类,不能被继承
 
-  String VS StringBuffer -  String保存的是字符串常量,里面的值不能更改,每次String类的更新实际上就是更改地址,效率较低 
-  StringBuffer保存的是字符串变量,里面的值可以更改,每次StringBuffer的更新实际上可以更新内容,不用每次更新地址,效率较高 //char[] value; //这个放在堆 
-  因为StringBuffer的字符序列是存放在char [] value,所以变化时不用每次都更换地址(即不是每次都创建新对象)所以效率高于String 
 
-  
-  StringBuffer的构造器 - StringBuffer( ) // 创建一个大小为16的char[],用于存放
- StringBuffer(CharSequence seq) //构造一个字符串缓冲区,它包含与指定的CharSequence相同的字符
- StringBuffer(int capacity) //capacity 容量 构造一个不带字符但具有初始容量的字符串缓冲区,即对char[]大小进行指定
- StringBuffer(String str) //构造一个字符串缓冲区,并将其内容初始化为指定的字符串内容(char[]数组长度增加了16)
 
-  String与StringBuffer互相转换 -  String==>StringBuffer String str = "a"; //方式一,使用构造器 //返回的是StringBuffer对象,对str没有任何影响 StringBuffer str1 = new StringBuffer("str"); //方式二 使用append()方法 StringBuffer stringBuffer = new StringBuffer(); stringBuffer.append(str);
-  StringBuffer==>String //方式一 使用toString方法 StringBuffer strb = new StringBuffer("a"); String strstr = strb.toString(); //方式二,使用构造器 String str2 = new String(strb); //strb为空时会报空指针异常,因为源码需要用到strb.length()
 
-  
-  StringBuffer常用方法 - append()–增加,如果参数为空,调用appendNull方法,StringBuffer内容为“null”
- delete(11,14)–删除11-14的字符,[11,14),包含11不含14
- replace(9,11,“a”)–使用a替换9-11的字符[9-11),包含9不包含11
- indexOf(“qaq”)–查找指定的字串在字符串中第一次出现的索引,如果找不到返回-1
- insert(9,“ak”)–在索引为9的位置插入ak,原来索引为9的内容自动后移
- length()–返回长度
 
StringBuilder类
-  基本介绍 - 一个可变的字符序列。此类提供一个与StringBuffer兼容的API,但不保证同步(StringBuilder不是线程安全)。该类被设计用作 StringBuffer的一个简易替换,用在字符串缓冲区被单个线程使用的时候。如果可能,建议优先采用该类,因为在大多数实现中,它比 StringBuffer 要快。
- 在StringBuilder上的主要操作是append和 insert方法,可重载这些方法,以接受任意类型的数据。
 
-  常用方法 与StringBuffer方法一样 - StringBuilder继承 AbstractStringBuilder类
- 实现了Serializable ,,说明StringBuilder对象是可以串行化(对象可以网络传输,可以保存到文件)
- StringBuilder是final类,不能被继承
- StringBuilder对象字符序列,仍然是存放在其父类 AbstractStringBuilder的 char[] value;因此,字符序列是堆中
- StringBuilder 的方法,没有做互斥的处理,即没有synchronized关键字,因此在单线程情况下使用
 
-  String vs StringBuffer vs StringBuilder -  StringBuilder 和 StringBuffer非常类似,均代表可变的字符序列,而且方法也一样 
-  String:不可变字符序列,效率低,但是复用率高(一个常量池的字符串可以有多个引用)。 
-  StringBuffer:可变字符序列、效率较高(增删)、线程安全(有synchronized关键字,同步的意思) 
-  StringBuilder:可变字符序列、效率最高、线程不安全 
-  String使用注意说明: String s = "a";//创建了一个字符串 s += "b";//实际上原来的"a"字符串对象已经丢弃了,现在又产生了一个字符串s+"b”(也就是"ab")。 //如果多次执行这些改变串内容的操作,会导致大量副本字符串对象存留在内存中,降低效率。如果这样的操作放到循环中,会极大影响程序的性能=> //结论:如果我们对String 做大量修改,不要使用String,用StringBuffer
-  效率测试 StringBuilder > StringBuffer > String 
 
-  
-  String、StringBuffer、StringBuilder使用原则 1.如果字符串存在大量的修改操作,一般使用 StringBuffer 或StringBuilder 2.如果字符串存在大量的修改操作,并在单线程的情况,使用StringBuilder 3.如果字符串存在大量的修改操作,并在多线程的情况,使用 StringBuffer 4、如果我们字符串很少修改,被多个对象引用,使用String, 比如配置信息等 
Math类
常见的方法(静态)
-  abs绝对值 
-  pow求幂 
-  ceil向上取整,返回大于等于该参数的最小整数(转成double) 
-  floor向下取整,返回小于等于该参数的最大整数(转成double) 
-  round四舍五入 相当于Math.floor(参数+0.5) 
-  sqrt求开方,参数为负返回NaN 
-  random求随机数 返回的是0 <= x < 1之间的随机小数 
//返回a-b之间的整数,a<=x<=b
//int num = (int) (a + Math.random() * (b - a + 1))
-  max求两个数的最大值 
-  min求两个数的最小值 
Arrays类
包含一系列静态方法,用于管理或操作数组(比如排序和搜索)
-  toString—返回数组的字符串形式 //int[] arr = { 1,2,3 }; //System.out.println(Arrays.toString(arr)); //输出[1,2,3]
-  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会影响整个排序结果, 这就充分体现了 接口编程+动态绑定+匿名内部类的综合使用.将来的底层框架和源码的使用方式, 会非常常见
*/
- binarySearch — 通过二分搜索法进行查找,要求必须排好序
int index = Arrays.binarySearch(arr,3);
/*
1、使用binarySearch通过二分搜索法进行查找,要求必须有序,无序不能用
2、如果数组中不存在该元素,返回应插入的位置+1的相反数,存在返回索引
*/
- copyOf 数组元素的复制
Integer[] newArr = Arrays.copyOf(arr,arr.length);
/*
1. 从 arr 数组中, 拷贝 arr.length 个元素到 newArr 数组中
2. 如果拷贝的长度 > arr.length 就在新数组的后面 增加 null
3. 如果拷贝长度 < 0 就抛出异常 NegativeArraySizeException
4. 该方法的底层使用的是 System.arraycopy()
*/
- fill数组元素的填充
lnteger[]num = new Integer[]{9,3,23};
Arrays.fill(num, 99);
//使用 99 去填充 num 数组, 可以理解成是替换原来所有的元素
//num 变成 99 99 99
- equals比较两个数组元素内容是否完全一致,不是地址
boolean equals = Arrays.equals(arr,arr2);
//1. 如果 arr 和 arr2 数组的元素一样, 则方法 true;
//2. 如果不是完全一样, 就返回 false
- 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;
    }
}










