分类 JavaSE 下的文章

1.1 Arrays基本使用

Arrays是操作数组的工具类,它可以很方便的对数组中的元素进行遍历、拷贝、排序等操作。

下面我们用代码来演示一下:遍历、拷贝、排序等操作。需要用到的方法如下

/**
 * 目标:掌握Arrays类的常用方法。
 */
public class ArraysTest1 {
    public static void main(String[] args) {
        // 1、public static String toString(类型[] arr): 返回数组的内容
        int[] arr = {10, 20, 30, 40, 50, 60};
        System.out.println(Arrays.toString(arr));

        // 2、public static 类型[] copyOfRange(类型[] arr, 起始索引, 结束索引) :拷贝数组(指定范围,包前不包后)
        int[] arr2 = Arrays.copyOfRange(arr, 1, 4);
        System.out.println(Arrays.toString(arr2));

        // 3、public static copyOf(类型[] arr, int newLength):拷贝数组,可以指定新数组的长度。
        int[] arr3 = Arrays.copyOf(arr, 10);
        System.out.println(Arrays.toString(arr3));

        // 4、public static setAll(double[] array, IntToDoubleFunction generator):把数组中的原数据改为新数据又存进去。
        double[] prices = {99.8, 128, 100};
        //                  0     1    2
        // 把所有的价格都打八折,然后又存进去。
        Arrays.setAll(prices, new IntToDoubleFunction() {
            @Override
            public double applyAsDouble(int value) {
                // value = 0  1  2
                return prices[value] * 0.8;
            }
        });
        System.out.println(Arrays.toString(prices));

        // 5、public static void sort(类型[] arr):对数组进行排序(默认是升序排序)
        Arrays.sort(prices);
        System.out.println(Arrays.toString(prices));
    }
}

1.2 Arrays排序对象数组

刚才我们使用Arrays操作数组时,数组中存储存储的元素是int类型、double类型,是可以直接排序的,而且默认是升序排列。

如果数组中存储的元素类型是自定义的对象,如何排序呢?接下来,我们就学习一下Arrays如何对对象数组进行排序。

首先我们要准备一个Student类,代码如下:

public class Student{
    private String name;
    private double height;
    private int age;

    public Student(String name, double height, int age) {
        this.name = name;
        this.height = height;
        this.age = age;
    }

@Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", height=" + height +
                ", age=" + age +
                '}';
    }
}

然后再写一个测试类,往数组中存储4个学生对象,代码如下。此时,运行代码你会发现是会报错的。

public class ArraysTest2 {
    public static void main(String[] args) {
        // 目标:掌握如何对数组中的对象进行排序。
        Student[] students = new Student[4];
        students[0] = new Student("蜘蛛精", 169.5, 23);
        students[1] = new Student("紫霞", 163.8, 26);
        students[2] = new Student("紫霞", 163.8, 26);
        students[3] = new Student("至尊宝", 167.5, 24);

        // 1、public static void sort(类型[] arr):对数组进行排序。
Arrays.sort(students);
System.out.println(Arrays.toString(students));
    }
}

上面的代码为什么会报错呢?因为Arrays根本就不知道按照什么规则进行排序。为了让Arrays知道按照什么规则排序,我们有如下的两种办法。

  • 排序方式1:让Student类实现Comparable接口,同时重写compareTo方法。Arrays的sort方法底层会根据compareTo方法的返回值是正数、负数、还是0来确定谁大、谁小、谁相等。代码如下:
public class Student implements Comparable<Student>{
    private String name;
    private double height;
    private int age;
    
    //...get、set、空参数构造方法、有参数构造方法...自己补全

    // 指定比较规则
    // this  o
    @Override
    public int compareTo(Student o) {
        // 约定1:认为左边对象 大于 右边对象 请您返回正整数
        // 约定2:认为左边对象 小于 右边对象 请您返回负整数
        // 约定3:认为左边对象 等于 右边对象 请您一定返回0
/* if(this.age > o.age){
            return 1;
        }else if(this.age < o.age){
            return -1;
        }
        return 0;*/

        //上面的if语句,也可以简化为下面的一行代码
        return this.age - o.age; // 按照年龄升序排列
        // return o.age - this.age; // 按照年龄降序排列
    }
    
    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", height=" + height +
                ", age=" + age +
                '}';
    }
}
  • 排序方式2:在调用Arrays.sort(数组,Comparator比较器);时,除了传递数组之外,传递一个Comparator比较器对象。Arrays的sort方法底层会根据Comparator比较器对象的compare方法方法的返回值是正数、负数、还是0来确定谁大、谁小、谁相等。代码如下
public class ArraysTest2 {
    public static void main(String[] args) {
        // 目标:掌握如何对数组中的对象进行排序。
        Student[] students = new Student[4];
        students[0] = new Student("蜘蛛精", 169.5, 23);
        students[1] = new Student("紫霞", 163.8, 26);
        students[2] = new Student("紫霞", 163.8, 26);
        students[3] = new Student("至尊宝", 167.5, 24);

// 2、public static <T> void sort(T[] arr, Comparator<? super T> c)
        // 参数一:需要排序的数组
        // 参数二:Comparator比较器对象(用来制定对象的比较规则)
        Arrays.sort(students, new Comparator<Student>() {
            @Override
            public int compare(Student o1, Student o2) {
                // 制定比较规则了:左边对象 o1   右边对象 o2
                // 约定1:认为左边对象 大于 右边对象 请您返回正整数
                // 约定2:认为左边对象 小于 右边对象 请您返回负整数
                // 约定3:认为左边对象 等于 右边对象 请您一定返回0
//                if(o1.getHeight() > o2.getHeight()){
//                    return 1;
//                }else if(o1.getHeight() < o2.getHeight()){
//                    return -1;
//                }
//                return 0; // 升序
                 return Double.compare(o1.getHeight(), o2.getHeight()); // 升序
                // return Double.compare(o2.getHeight(), o1.getHeight()); // 降序
            }
        });
        System.out.println(Arrays.toString(students));
    }
}

Steam流

操作数组或集合的一个知识点
public static void main(String[] args) {
        //认识steam流
        List<String> list=new ArrayList<>();
        Collections.addAll(list,"张三1","张四","王五","赵五");

//找出姓张 并且名字是三个字的存在一个新集合中
        List<String> newList =new ArrayList<>();
        for(String s : list){
            if(s.startsWith("张") && s.length()==3){
                newList.add(s);
            }


        }
        System.out.println(newList);
        System.out.println("--------------------------");

    //使用steam流用来实现对象集合数据的操作
        List<String> listS = list.stream().filter(s -> s.startsWith("张") && s.length() == 3).collect(Collectors.toList());
        System.out.println(listS);






     //如何获取List集合的Stream流
        List<String> list1=new ArrayList<>();
        Collections.addAll(list1,"张三1","张四","王五","赵五");
        System.out.println(list1.stream());


        //如何获取Set集合的stream流
        Set<String> strings = new HashSet<>();
        System.out.println(strings.stream());

        //如何获取Map集合的Stream流
        HashMap<String, String> map = new HashMap<>();
        System.out.println(map.keySet().stream());

        System.out.println(map.values().stream());

        System.out.println(map.entrySet().stream());


        //如何获取属猪的stream流

        String[] arr={"java1","java2","java3","java4"};
        System.out.println(Arrays.stream(arr));
        System.out.println(Stream.of(arr));





    }

Date类

//1.创建日期对象
Date d = new Date();
System.out.println(d);
  
  
//2. 拿到时间戳
long time = d.getTime();
System.out.println(time);
  
  
//只获取时间戳推荐使用
//System.currentTimeMillis();
  
//3.把时间戳转为日期对象 
Date date = new Date(time);
long time1 = date.getTime();
System.out.println(time1);

  
//把时间对象的时间设置为当前时间的时间戳
xDate date1 = new Date();
date1.setTime(time);
System.out.println(date1.getTime());

SimpleDateFormat类

//SimpleDateFormat 用于格式化日期对象 变成想看到的日期格式 返回String类型
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String format = sdf.format(new Date());
System.out.println(format);


 String lastTime = "2023/05/07";
//字符串日期转换成Date日期对象
Date parse = sdf.parse(lastTime);
System.out.println(parse);

SimpleDateFormat存在的问题

/**
 *  目标:搞清楚为什么要用JDK 8开始新增的时间类。
 */
public class Test {
    public static void main(String[] args) {
        // 传统的时间类(Date、SimpleDateFormat、Calendar)存在如下问题:
        // 1、设计不合理,使用不方便,很多都被淘汰了。
        Date d = new Date();
        //System.out.println(d.getYear() + 1900);

        Calendar c = Calendar.getInstance();
        int year = c.get(Calendar.YEAR);
        System.out.println(year);

        // 2、都是可变对象,修改后会丢失最开始的时间信息。

        // 3、线程不安全。

        // 4、不能精确到纳秒,只能精确到毫秒。
        // 1秒 = 1000毫秒
        // 1毫秒 = 1000微妙
        // 1微妙 = 1000纳秒
    }
}

精度丢失

//精度丢失
System.out.println(0.1+0.2);
System.out.println(1.0-0.32);
System.out.println(1.015*100);
System.out.println(1.301/100);

BigDecimal

//注意new出来的 BigDecimal() 括号写字符串
BigDecimal b1=new BigDecimal("1.2");
//使用valueOf()
BigDecimal b2=BigDecimal.valueOf(1.2);

//求和
System.out.println(b2.add(b1));
//减
System.out.println(b2.subtract(b1));
//相乘
System.out.println(b2.multiply(b1));
//除
System.out.println(b2.divide(b1));

//算数异常
//当除不尽时会报错
BigDecimal b3=BigDecimal.valueOf(1);
BigDecimal b4=BigDecimal.valueOf(3);
//报错
System.out.println(b3.divide(b4));
//解决方案
//四舍五入
System.out.println(b3.divide(b4, RoundingMode.HALF_UP));
//向上取整
System.out.println(b3.divide(b4, RoundingMode.CEILING));
//向下取整
System.out.println(b3.divide(b4, RoundingMode.FLOOR));

保留小数位

System.out.println(b3.divide(b4,2, RoundingMode.FLOOR));

把BigDecimal转换为doubleValue

double doubleValue=b5.doubleValue();

//终止java虚拟机
System.exit(0);

//获取系统当前戳
//1970.1.1  00:00:00 到当前时间的毫秒
System.currenTimeMillis();

//求这段代码时间用了多少时间
long t1=System.currenTimeMillis();
long t2=System.currenTimeMillis();
System.out.println(t2-t1);

//绝对值
Math.abs(123);
//向上取整
Math.ceil(1.1);
//向下取整
Math.floor(2.3);
//四舍五入
Math.round(3.45);
//最大最小值
Math.max(100,2);
Math.min(3,1000);

//StringBuilder的创建
StringBuilder sb=new StringBuilder("java")

//拼接内容 append(String s);
sb.append("123");

//支持链式编程
StringBuilder sb1=new StringBuilder("张三");
sb1.append("李四").append("王五");
System.out.println(sb1);
//反转操作 reverse()
sb1.reverse();

//返回字符串长度 length()
System.out.println(sb1.length());

//把StringBuilder对象转换成String 类型 .toString();

String s=sb1.toString();

StringBuider的好处

比String拼接字符串的效率快

基本数据类型对应的包装类(引用数据类型)
byteByte
shortShort
intInteger
longLong
chatCharacter
floatFloat
doubleDouble
booleanBoolean

Integer对象的创建

1. new 有参
Integer a=new Integer(123);
2. 静态方法 valueOf()
Integer b=Integer.valueOf(20);
3. 自动装箱写法 (java自动把基本数据类型对应的包装类)
Integer c=30; //Integer.valueOf(30)

//4.自动拆箱(java自动把包装类装维基本数据类型)
int d=c;

泛型
//ArrayList<String>
//集合内只能装String类型的数据
//泛型的作用 在编译阶段 检查集合的元素的类型
//在java1.7开始 泛型后面的部分可以不写
ArrayList<String> list1=new ArrayList<>();
list1.add("123");
list1.add("字符串");

泛型类

格式
/**
 * 自定义泛型类
 * @author TongHui
 * @date 2023.05.04 15:33
 * @param <E> 我的集合中的元素类型
 */
public class MyArrayList <E>{
    private Object[] array=new Object[10];
    private int index;

    /**
     * 添加元素
     * @param e
     */
    public void add(E e){
        array[index]=e;
        index++;
    }

    /**
     * 获取元素
     * @param index
     * @return
     */
    public E get(int index){
        return (E) array[index];
    }
}
public class Test {
    public static void main(String[] args) {
        MyArrayList<String> stringMyArrayList = new MyArrayList<>();
        stringMyArrayList.add("123123");
        System.out.println(stringMyArrayList.get(0));
    }



    public static <T> void test(T t){
        System.out.println(t.toString());
    }

    public static <T> T test2(T t){
        return t;
    }

}

枚举时一个特殊的类,他的格式是:
public enum 枚举类名{
    枚举项1,枚举项2,枚举项3;
}

其实枚举项就表示枚举类的对象,只是这些对象在定义枚举类时就预先写好了,以后就只能用这几个固定的对象。

案例

public enum A{
    X,Y,Z;
}
想要获取枚举类中的枚举项,只需要用类名调用就可以了
public class Test{
    public static void main(String[] args){
        //获取枚举A类的,枚举项
        A a1 = A.X;
        A a2 = A.Y;
        A a3 = A.Z;
    }
}

枚举项是当前这个枚举

枚举项是static修饰的

枚举项被finale修饰

枚举的应用场景

API响应
public enum ResponseCodeEnum{
    //成功 返回SUCCESS信息 和 200状态码
    //失败 返回ERROR 信息 和 500状态码
    SUCCESS(200,"SUCCESS"),
    ERROR(500,"ERROR")
    ;
    //枚举有参构造器 为什么要提供无参?
    //只想用有参枚举项
    private int code;
    private String desc;
    ResponseCodeEnum(int code,String desc){
        this.code=code;
        this.desc=desc;
    }
    public int getCode(){
        return code;
    }
    public String getDesc(){
        return desc;
    }
}