Java工具类

本文涉及的产品
实时计算 Flink 版,5000CU*H 3个月
检索分析服务 Elasticsearch 版,2核4GB开发者规格 1个月
实时数仓Hologres,5000CU*H 100GB 3个月
简介: Java工具类

工具类

注意:下面所讲的所有方法导包都是

import java.util.

定义:提供一组静态方法实用函数来执行特定任务的类。

场景:常用于封装,以便于在程序的不同部分中重复使用。

作用:下面是Java工具类的一些关键特点和常见用途:

  1. 封装常用操作:工具类封装了一些常见的操作,如字符串处理、日期时间处理、文件操作、数学计算等。它们提供了一组静态方法,可以直接调用而无需实例化类对象。
  2. 提高代码复用性:通过使用工具类,可以将常用的功能和方法封装起来,使其可以在不同的项目和场景中被重复使用,从而提高代码的复用性。
  3. 简化开发流程:工具类提供了一些高级的功能和算法,可以简化开发流程。开发人员可以直接使用这些方法,而无需自己实现复杂的逻辑。
  4. 提供工具方法:工具类还提供了一些实用的工具方法,如类型转换、集合操作、异常处理等。这些方法可以帮助开发人员更方便地处理数据和异常情况。
  5. 增强程序性能:一些工具类通过优化算法和数据结构,提供了高效的实现方式,从而提升程序的性能。
  6. 扩展功能和库:Java工具类还可以作为功能和库的扩展,为特定领域或特定需求提供更专业的功能和方法。
public class MathUtils {
   
   

  // 计算两个整数的和
  public static int add(int a, int b) {
   
   
    return a + b;
  }

  // 判断一个数是否为偶数
  public static boolean isEven(int num) {
   
   
    return num % 2 == 0;
  }

  // 计算圆的面积
  public static double calculateCircleArea(double radius) {
   
   
    return Math.PI * radius * radius;
  }

  // 其他实用方法可以在这里添加...
}
在工具类中使用静态方法的原因

1.无需创建对象/实例,通过类名进行直接调用

2.可以在任何地方直接访问,可以在程序中的任何位置调用到工具类中的方法。

3.代码复用,静态方法在不同地方中重复使用的时候,不需要每次都创建对象

4.工具类中的实用方法一般是具有通用性的,与具体的对象实例无关

注意:静态方法在某些情况下虽然非常有用,但它们无法访问非静态成员(变量或者方法)。

工具类中的包装类

自动装箱和拆箱(只存在于基本数据类型的包装类中)

Integer c = 5;
//自动装箱现象:即自动地将数据装到引用数据类型之中
String b = "";
System.out.println(b+5);
//自动拆箱 即将b+5转为整数5
//如果b为null 会触发空指针异常

所有的基本类型的包装类的都有一个以字符串作为唯一参数的构造器。

// eg:public Double(String s)

包装类定义:是Java提供的一组类,用于将基本数据类型包装成对象类。

​ 包装类中提供的方法,可以用于在基本数据类型和对象之间进行转换,以执行与基本数据类型相关的操作。

​ 基本数据类型和包装类都是常量,不能对本身进行修改。

契合面向对象的风格

对象的可变性与内存固定

引用数据类型的对象在内存中的大小都是固定的,而对象的可变性与内存固定无关,可变性表示的只是一种状态。

String

“在大数据中,所有的数据都是字符串”,数据的主体实际上是行为数据,而这种行为数据通常是以文本、文档的形式存储,也就是字符串的形式,通过解析成不同类型的数据来进行计算。

字符串的重要性

  1. 通用性和灵活性:字符串是一种通用的数据类型,可以表示几乎任何类型的数据。通过将所有数据表示为字符串,可以在不限定特定数据类型的情况下处理各种数据
  2. 数据格式的统一:将所有数据表示为字符串可以避免不同数据类型之间的格式差异。不同的数据类型有不同的表示方式和规则,但将它们统一为字符串可以消除这些差异,使数据处理更加一致和简化。
  3. 数据传输和存储的简化:在数据传输和存储过程中,将数据表示为字符串可以减少数据转换和编码的复杂性。大多数数据传输和存储系统都能够直接处理字符串,因此使用字符串表示数据可以简化数据的传输和存储过程
  4. 数据处理和分析的便利性:大多数数据处理和分析工具都提供了丰富的字符串处理功能和库,使得以字符串形式表示的数据可以进行各种复杂的操作和分析。通过利用字符串处理工具和算法,可以从字符串中提取、转换和分析所需的数据。
字符串的性质
  • 字符串的本质是字符数组->构造方法可以传入字符数组构造字符串,也可以根据StringBuilder进行创建
public final class String{
   
   
    private final char value[];

    private int hash;// 用于缓存字符串的哈希码,因为String经常被用于比较,如果每次比较都需要重新计算其hashcode的值的话
                                  // 无疑是比较麻烦的,保存一个hashcode的缓存能够优化这样的操作。
}
char data[] = {
   
   'a','b','c'};
String str = new String(data);
  • String实现了三个接口,分别是Serializable,Comparable,CharSequence

    Serializable:可序列化

    Comparable:可以比较大小

    CharSequence:字符串序列接口

字符串的方法
//字符串中的特定字符
String str1 = "abc";
System.out.println(str1.startsWith("a"));
System.out.println(str1.endsWith("bc"));
String str2 = "henry.chen@hotmail.com";
System.out.println(str2.indexOf("."));
System.out.println(str2.lastIndexOf("."));
//实现提取账号和公司地址        
final int pos = str2.indexOf("@");
System.out.println(str2.substring(pos+1));
System.out.println(str2.substring(0, pos));

String str1 = "henry.chen@hotmail.com";
System.out.println(str1.length());//本质是字符数组
final String str2 = "    henry.chen@hotmail.com  ";
System.out.println(str2.trim());

String str1 = "henrychen@hotmail.com";
System.out.println(str1.matches("^[a-z0-9]{3,20}@[a-z0-9]{2,18}\\.(com|cn|net|org)$"));

//关于String中的三种比较
String str1 = "abc";
System.out.println(str1.equals("abc"));
System.out.println(str1.compareTo("abc"));
System.out.println(str1.equalsIgnoreCase("Abc"));

//“回归本质”
str.toCharArray()
//假设此时chars中的内容为[a,b,c]    
new String(chars)//abc
Arrays.toString(charArray)//[a,b,c] 以数组的形式返回表示字符数组的字符串

//字符串分隔
String str = "13,45,63";
final String[] s = str.split(",");
for (String s1 : s) {
   
   
    System.out.println(s1);
}
String str1 = "13,45?56.67";
System.out.println(str.split(",|\\.|\\?"));
String str2 = "13,,,45我是谁67.";
str.split("[^0-9]+");
str.split("")

StringTokenizer it = new StringTokenizer(line,delimiter);//以delimiter分隔符分隔line内容,并获取一个存放分隔后内容的迭代器。
if(it.countTokens()>0){
   
   
  while(it.hasMoreElements()){
   
   
    final String text = it.nextToken();
  }
}

//替换
String str = "13,45,63";
System.out.println(str.charAt(3));
System.out.println(str.replaceFirst(",", "|"));
System.out.println(str.replaceAll("[^0-9]", ","));

//格式化(类比System.out.printf())
String name = "刘亦菲";
int age = 22;
char gender = '女';
System.out.println(String.format("姓名:%s,年龄:%d,性别:%s", name, age, gender));

//查找
str1.contains(str2) //返回boolean值
//字符串拼接
String name = "刘亦菲";
int age = 22;
char gender = '女';
float weight = 92.3456f;
//两种用于长度较短字符串的方法
System.out.println(String.format("姓名:%s,年龄:%d,性别:%s,体重:%.2f", name, age, gender,weight));

System.out.println(MessageFormat.format("姓名:{0},年龄:{1},性别:{2},体重:{3,number,#.##}", name, age, gender, weight));

final StringBuilder builder = new StringBuilder("");//常用于拼接长度不确定或者长度很长的字符串
builder.append(name);
builder.append(",");
builder.append(age);
builder.append(",");
builder.append(weight);

//将非字符串类型转化为字符串类型(类型统一处理)
String.valueOf()//含有各种类型的重载
//将自定义类型转化为字符串类型
@Override toString()    
//将字符串类型转化为基本数据类型
Xxx val = Xxx.parseXxx(String s);
//将字符串类型转化为引用数据类型
Xxx val = Xxx.valueOf(String s);

// 字符串的其他解析
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String content = br.readLine();
client.getOutputStream().write(content.getBytes(CharSet.forName("UTF-8"))));//注意客户端向服务器发送消息的时候,write()方法中只能传入Bytes[]数组,此处将控制台输入的字符串解析成Bytes数组。

关于字符串方法的一些补充

CompareTo()

字符串的字典顺序是一种按照字符的Unicode值进行比较的顺序,在Unicode顺序中,每个字符都被分配了一个唯一的数字,逐个字符进行比较。

  • 如果两个字符串相等,返回值为0。

  • 如果当前字符串小于目标字符串,返回一个负整数。

  • 如果当前字符串大于目标字符串,返回一个正整数。

    相较equals()而言,能额外的比较出大小关系。

CharSquence

CharSequence是一个接口,表示字符序列

trim()方法

判断空串:trim()后判断长度是否为0/isEmpty()方法

    public String trim() {
   
   
        int len = value.length;
        int st = 0;
        char[] val = value; // value为字符串的字符数组

        while ((st < len) && (val[st] <= ' ')) {
   
   
            st++;
        }
        while ((st < len) && (val[len - 1] <= ' ')) {
   
   
            len--;
        }
        return ((st > 0) || (len < value.length)) ? substring(st, len) : this;
    }

字符序列的定义

  • 可变字符序列 StringBuilder StringBuffer 提供了一系列方法来修改字符串的内容

    StringBuilder相较于StringBuffer来说,是非线程安全的,由于加锁是一个比较耗时的操作,会影响性能,所以String底层使用StringBuilder作为字符串拼接。

  • 不可变字符序列 String 每次对不可变字符序列进行修改时,都会创建一个新的字符序列对象

    • 字符串的不可变性

      便于多个引用指向同一个对象,如果字符串是可变的,那么一个引用操作改变了对象的值,也会对其他引用造成影响,显然是不合理的。

StringBuilder
char[] value;// 存储字符数组

int count;// 字符串使用的计数
  • 扩容机制

    ensureCapacityInternal方法:

    扩容

注意

在大量循环拼接字符串的时候需要注意,当使用+连接符的时候,JVM会隐式创建StringBuilder对象,内存中就会多了很多StringBuilder的无用对象。

改进:初始化一个StringBuilder对象之后再循环对其进行拼接。

StringBuilder

Integer
  • parseInt(String s): 将字符串转换为整数类型。

    Integer.parseInt(String s,int a)//表示将字符串转化为a进制的数
    Integer.toBinaryString()
    
  • toString(int i): 将整数转换为字符串类型。

  • valueOf(int i): 将整数转换为Integer对象。

String numberStr = "123";
int number = Integer.parseInt(numberStr);
String str = Integer.toString(number);
Integer integer = Integer.valueOf(number);
System.out.println(Integer.highestOneBit(5));//4 返回整数对应二进制数最高位的对应数值 101对应最高位数值为1*2的2次方 = 4
Double
  • parseDouble(String s): 将字符串转换为双精度浮点数类型。
  • toString(double d): 将双精度浮点数转换为字符串类型。
  • valueOf(double d): 将双精度浮点数转换为Double对象。
javaCopy codeString numberStr = "3.14";
double number = Double.parseDouble(numberStr);
String str = Double.toString(number);
Double doubleObj = Double.valueOf(number);
Boolean
  • parseBoolean(String s): 将字符串转换为布尔类型。
  • toString(boolean b): 将布尔类型转换为字符串。
  • valueOf(boolean b): 将布尔类型转换为Boolean对象。
javaCopy codeString boolStr = "true";
boolean bool = Boolean.parseBoolean(boolStr);
String str = Boolean.toString(bool);
Boolean booleanObj = Boolean.valueOf(bool);
Character
  • toString(char c): 将字符类型转换为字符串。
  • valueOf(char c): 将字符类型转换为Character对象。
javaCopy codechar ch = 'A';
String str = Character.toString(ch);
Character charObj = Character.valueOf(ch);

final char a = Character.toLowerCase('A');
final char b = Character.toUpperCase('a');
final boolean a = Character.isLetterOrDigit('a');
final boolean isAlphabet = Character.isAlphabetic('7');
final boolean isDigit = Character.isDigit('6');
final boolean isLetter = Character.isLetter('a');
Character.isWhitespace(' ');
枚举
EnumSet
import java.util.EnumSet;

enum Day {
   
   
    MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY
}

public class EnumSetExample {
   
   
    public static void main(String[] args) {
   
   
        EnumSet<Day> weekdays = EnumSet.range(Day.MONDAY, Day.FRIDAY);

        System.out.println(weekdays); // 输出:[MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY]

        weekdays.add(Day.SATURDAY);
        weekdays.add(Day.SUNDAY);

        System.out.println(weekdays); // 输出:[MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY]

        weekdays.remove(Day.MONDAY);

        System.out.println(weekdays); // 输出:[TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY]

        weekdays.clear();

        System.out.println(weekdays); // 输出:[]
    }
}
EnumMap
import java.util.EnumMap;

enum Color {
   
   
    RED, GREEN, BLUE
}

public class EnumMapExample {
   
   
    public static void main(String[] args) {
   
   
        EnumMap<Color, Integer> colorCount = new EnumMap<>(Color.class);

        colorCount.put(Color.RED, 5);
        colorCount.put(Color.GREEN, 10);
        colorCount.put(Color.BLUE, 7);

        System.out.println(colorCount); // 输出:{RED=5, GREEN=10, BLUE=7}

        int greenCount = colorCount.get(Color.GREEN);
        System.out.println("Green count: " + greenCount); // 输出:Green count: 10

        colorCount.remove(Color.GREEN);
比较

(基础,底层)底层数据结构:EnumSet和Set相比,底层数据结构使用了位向量来表示了枚举值的存在与否,位向量中的每一位都对应着一个枚举值,通过位操作进行标记和查询,能够更紧凑的存储和标识。

(特性)枚举类型的特性:枚举类型的值是有限且连续的,代表的是一组离散的常量。并且可以高效地进行集合操作,如并集、交集和差集等。

(特性)类型安全:EnumSet是针对枚举类型的集合,它在编译期间就能够保证类型的安全性。这意味着您无法将错误类型的元素添加到EnumSet中,并且在使用EnumSet时无需进行类型转换。这种类型安全性使得EnumSet在使用时更加方便和可靠。

底层数据结构:由于枚举类型的值是有限且连续的,数组可以直接通过枚举值来作为索引访问对应的值,无需进行哈希计算和查找。

(特性)这使得EnumMap可以使用一个数组来存储映射的值,数组的长度等于枚举类型的值的个数。相比于一般的Map实现,EnumMap不需要考虑哈希冲突、扩容等问题,因此在性能上更加高效。

(特性)类型安全:EnumMap是针对枚举类型的键的映射,它在编译期间就能够保证类型的安全性。这意味着您无法将错误类型的键添加到EnumMap中,并且在使用EnumMap时无需进行类型转换。这种类型安全性使得EnumMap在使用时更加方便和可靠。

枚举Enum

枚举的本质:一个事物的状态会发生变化,通过枚举类型表示事物的所有状态,通过状态来描述任务。

enum Status{
   
   
    战士,道士,法师
}
public static void main(String[] args){
   
   
    for(Status value : Status.values()){
   
   
        System.out.println(value);
        System.out.println(value.ordinal);
    }
   switch(status){
   
   
        case 道士:

         break;
   }
}

为什么不怎么用枚举了?

public interface Status {
   
   
    int SOLDIER = 0;
    int TAOIST = 1;
    int MAGE = 2;
}
//接口中的属性默认为静态常量,类实现接口进行状态的调用。

EnumSet常用方法:

  1. EnumSet.allOf(EnumClass):创建一个包含指定枚举类中所有元素的EnumSet
  2. EnumSet.noneOf(EnumClass):创建一个空的EnumSet,元素类型为指定的枚举类。
  3. EnumSet.of(EnumValue1, EnumValue2, ...):创建一个包含指定枚举值的EnumSet
  4. EnumSet.range(EnumValue1, EnumValue2):创建一个包含指定范围内的连续枚举值的EnumSet
  5. EnumSet.add(EnumValue):向EnumSet中添加指定的枚举值。
  6. EnumSet.remove(EnumValue):从EnumSet中移除指定的枚举值。
  7. EnumSet.contains(EnumValue):检查EnumSet是否包含指定的枚举值。
  8. EnumSet.isEmpty():检查EnumSet是否为空。
  9. EnumSet.size():返回EnumSet中的元素个数。
  10. EnumSet.copyOf(EnumSet):创建一个包含指定EnumSet中所有元素的副本。

EnumMap常用方法:

  1. EnumMap(EnumClass):创建一个新的EnumMap,键的类型为指定的枚举类。
  2. EnumMap.put(EnumKey, Value):将指定的键和值添加到EnumMap中。
  3. EnumMap.get(EnumKey):获取指定键对应的值。
  4. EnumMap.containsKey(EnumKey):检查EnumMap是否包含指定的键。
  5. EnumMap.containsValue(Value):检查EnumMap是否包含指定的值。
  6. EnumMap.remove(EnumKey):从EnumMap中移除指定键对应的键值对。
  7. EnumMap.isEmpty():检查EnumMap是否为空。
  8. EnumMap.size():返回EnumMap中的键值对个数。
  9. EnumMap.keySet():返回EnumMap中所有键的集合。
  10. EnumMap.values():返回EnumMap中所有值的集合。
Math(数学工具类)
  1. Math.abs(x):返回参数x的绝对值。
  2. Math.ceil(x):返回不小于参数x的最小整数。(返回值为double)
  3. Math.floor(x):返回不大于参数x的最大整数。(返回值为double)
  4. Math.round(x):返回参数x的四舍五入值。(返回值为int/long)
  5. Math.max(x, y):返回参数x和y中的较大值。
  6. Math.min(x, y):返回参数x和y中的较小值。
  7. Math.sqrt(x):返回参数x的平方根。
  8. Math.pow(x, y):返回x的y次幂。
  9. Math.scalb()
import java.math.BigDecimal;
import java.math.BigInteger;

public class BigDecimalBigIntegerExample {
   
   
    public static void main(String[] args) {
   
   
        // 使用BigDecimal进行高精度计算
        BigDecimal num1 = new BigDecimal("3.14159");
        BigDecimal num2 = new BigDecimal("2.71828");

        BigDecimal sum = num1.add(num2);
        BigDecimal difference = num1.subtract(num2);
        BigDecimal product = num1.multiply(num2);
        BigDecimal quotient = num1.divide(num2, 4, BigDecimal.ROUND_HALF_UP);
        //第二个参数 4 是表示结果的小数位数。这里设置为 4 表示希望结果保留四位小数。因为可能产生无限小数,所以必须要有保留位数。
        //第三个参数 BigDecimal.ROUND_HALF_UP 是指定舍入模式。在本例中,使用了舍入模式                     ROUND_HALF_UP,它表示当遇到等距离的两个数字时,将结果四舍五入到最接近的偶数。

        //当其他结果需要舍入的时候
        num1.setScale(2,RoundingMode.HALF_UP/CEILING/FLOOR)//三种不同的舍入模式,分别代表四舍五入 向上舍入 向下舍入(到最接近的整数)
        System.out.println("Sum: " + sum);
        System.out.println("Difference: " + difference);
        System.out.println("Product: " + product);
        System.out.println("Quotient: " + quotient);

        // 使用BigInteger进行大整数运算
        BigInteger bigNum1 = new BigInteger("12345678901234567890");
        BigInteger bigNum2 = new BigInteger("98765432109876543210");

        BigInteger sumBigInt = bigNum1.add(bigNum2);
        BigInteger differenceBigInt = bigNum1.min(bigNum2);
        BigInteger productBigInt = bigNum1.multiply(bigNum2);
        BigInteger divideBigInt = bigNum1.divide(bigNum2);

        System.out.println("Sum (BigInteger): " + sumBigInt);
        System.out.println("Difference (BigInteger): " + differenceBigInt);
        System.out.println("Product (BigInteger): " + productBigInt);
    }
}

注意:BigDecimal中的divide方法有舍去精度和舍入模式。通过使用BigDecimalBigInteger,我们可以进行精确的小数运算和大整数计算,避免了浮点数精度丢失整数溢出的问题。

请注意,对于BigDecimalBigInteger,它们的对象都是不可变的,意味着每个运算都会返回一个新的对象。因此,在进行连续的运算时,应该将结果赋值给一个新的BigDecimalBigInteger对象,而不是直接在原对象上进行修改。

BigDecimalBigInteger是Java中的引用类型,它们是不可变(immutable)的对象。因为它们的值是任意精度的,可以表示非常大或非常小的数值,所以需要使用对象来存储和操作这些值。

它们的值是存储在堆内存中的对象,而不是存储在栈内存中的变量。通过实例化创建对象,我们可以动态分配内存空间来存储大数值,(在创建对象时,内部会根据数值的大小本身为这些对象分配存储空间)避免了基本数据类型的固定内存限制。

传值的时候用字符串格式,因为字符串长度不受限。

日期和时间类

日期的本质是数值

  1. Date类:Date类是Java中用于表示日期和时间的类。它提供了一系列方法来获取和设置日期、时间以及执行日期和时间的计算。然而,Date类在Java 8之后已经过时,不推荐在新的代码中使用。建议使用java.time包中的新日期和时间API。

  2. Calendar类:Calendar类是Java中的一个抽象类,用于处理日期和时间的计算和操作。通过Calendar类,我们可以获取当前的日期和时间,对日期进行加减操作,设置特定的日期和时间,以及获取日期和时间的各个部分(年、月、日、时、分、秒等)。Calendar类提供了一些常用的静态方法来获取Calendar对象的实例。

  3. SimpleDateFormat类:SimpleDateFormat是Java中用于格式化和解析日期的类。它可以将日期对象转换为指定格式的字符串,或者将字符串解析为对应的日期对象。SimpleDateFormat使用一种模式字符串来定义日期的格式,模式字符串由一系列的字母和符号组成,每个字母和符号代表不同的日期和时间部分。一些常用的模式字母包括:yyyy(年份)、MM(月份)、dd(日期)、HH(小时)、mm(分钟)、ss(秒)等。

  4. 时间戳:时间戳(Timestamp)是表示特定时间点的数字或字符串值。它通常是一个长整型数值,表示从某个固定的起始时间(通常是1970年1月1日00:00:00 UTC)到特定时间点之间的经过的毫秒数、微秒数、纳秒数等。(最近的时间的时间戳为13位长整数)

    如果仅仅需要一个时间戳,不要用new Date(),而是要用以下两种方法获取系统自带的时间戳。

    final long l = System.currentTimeMillis();
    final long l = System.nanoTime();
    

    在程序运行前后,通过System.currentTimeMillis();差值判断程序运行时间间隔。

  5. 日期是可比较大小的

    final Date date1 = new Date(1573253263263L);
    final Date date2 = new Date(1423423423423L);
    System.out.println(date2.compareTo(date1));
    
   import java.text.SimpleDateFormat;
   import java.util.Date;

   public class DateFormatExample {
   
   
       public static void main(String[] args) {
   
   
           // 格式化日期 将日期按照一定形式转化为字符串
           SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
           String formattedDate = sdf.format(new Date());
           System.out.println("Formatted Date: " + formattedDate);

           // 解析日期字符串 将字符串按照一定形式转化为日期
           String dateString = "2023-05-15 14:30:00";
           try {
   
   
               Date parsedDate = sdf.parse(dateString);
               System.out.println("Parsed Date: " + parsedDate);
           } catch (Exception e) {
   
   
               e.printStackTrace();
           }
       }
   }

注意:在数据库中,日期都是以字符串String date = “2023-05-15 14:30:00”的形式存储的。

                final Calendar calendar = Calendar.getInstance();//获取一个当前日期和时间的实例
           String str = "2012-01-01 00:00:00";
           SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
           try {
   
   
               calendar.setTime(sdf.parse(str));
           } catch (ParseException e) {
   
   
               throw new RuntimeException(e);
           }
           System.out.println(calendar.getTime());
           //date中的很多方法是deprecated(过期的),是因为Calendar取代了他们。
           //一旦setTime之后,Calendar之间就会自动填充静态常量
           final Date dateTime = calendar.getTime();
           //拿到的是时间戳
           final long timeInMillis = calendar.getTimeInMillis();
           final int year = calendar.get(Calendar.YEAR);
           //月份满足规则 进 -1 出 +1(放进去的时候 月份-1,拿出来的时候 月份+1)
           final int month = calendar.get(Calendar.MONTH)+1;
           final int quarter = (month-1)/3+1;
           final int day = calendar.get(Calendar.DATE);
           final int hour = calendar.get(Calendar.HOUR);
           final int minute = calendar.get(Calendar.MINUTE);
           final int seconds = calendar.get(Calendar.SECOND);
           final int milliseconds = calendar.get(Calendar.MILLISECOND);
           final int weekDay = calendar.get(Calendar.DAY_OF_WEEK_IN_MONTH);
           final int weekMonth = calendar.get(Calendar.WEEK_OF_MONTH);
           final int weekYear = calendar.get(Calendar.WEEK_OF_YEAR);
           //截止到当前本周的业务数据
           final int weekDay = calendar.get(Calendar.DAY_OF_WEEK_IN_MONTH);
           calendar.add(Calendar.DATE,-weekDay);
           //截止到本季度的业务数据 即我们需要求出当前季度所属月份区间的第一个月份 这需要先算出季度
           month = (quarter-1)*3+1;
           calendar.set(Calendar.MONTH,month-1);
           calendar.set(Calendar.DATE,1);
           System.out.println(sdf.format(calendar.getTime()));//注意setTime/getTime对于月份来说,自动有进-1出+1的机制。

calendar语法在大数据中的作用:

1.通过数据库的脚本自带的函数按条件抽取一段数据,获取某段时间的数据。

2.数据没有时间就没有意义。

3.通过方法计算来明确特定时间节点到当前时间的时间间隔。

  • before&after方法

    final String strDateSmall = "2021-05-11";
    final String strDateBig = "2021-05-11";
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
    Calendar dateSmall = Calendar.getInstance();
    Calendar dateBig = Calendar.getInstance();
    dateSmall.setTime(sdf.parse(strDateSmall));
    dateBig.setTime(sdf.parse(strDateBig));
    System.out.println(dateSmall.after(dateBig));
    

如果两者日期相同,before|after|A.compareTo(B)>0|A.compareTo(B)<0的结果都为false

Objects工具类
  • Objects.nonnull():如果非空,...
  • Objects.equals(Object a,Object b):检查两个对象是否相等
  • Objects.hashCode(Object o):返回对象的哈希码
目录
相关文章
|
1月前
|
算法 搜索推荐 Java
java 后端 使用 Graphics2D 制作海报,画echarts图,带工具类,各种细节:如头像切割成圆形,文字换行算法(完美实验success),解决画上文字、图片后不清晰问题
这篇文章介绍了如何使用Java后端技术,结合Graphics2D和Echarts等工具,生成包含个性化信息和图表的海报,并提供了详细的代码实现和GitHub项目链接。
103 0
java 后端 使用 Graphics2D 制作海报,画echarts图,带工具类,各种细节:如头像切割成圆形,文字换行算法(完美实验success),解决画上文字、图片后不清晰问题
|
1月前
|
Java
Java 些许公共工具类
Java 些许公共工具类
14 1
|
3月前
|
缓存 前端开发 Java
【前端学java】java基础巩固复习巩固语法练习-工具类的封装(14)
【8月更文挑战第10天】java基础巩固,工具类的封装
26 1
【前端学java】java基础巩固复习巩固语法练习-工具类的封装(14)
|
3月前
|
Java
Java应用结构规范问题之在UnitConvertUtils工具类将千米转换为米的问题如何解决
Java应用结构规范问题之在UnitConvertUtils工具类将千米转换为米的问题如何解决
|
3月前
|
存储 设计模式 安全
Java GenericObjectPool 对象池化技术--SpringBoot sftp 连接池工具类
Java GenericObjectPool 对象池化技术--SpringBoot sftp 连接池工具类
50 0
|
4月前
|
设计模式 存储 安全
Java面试题:设计一个线程安全的单例类并解释其内存占用情况?使用Java多线程工具类实现一个高效的线程池,并解释其背后的原理。结合观察者模式与Java并发框架,设计一个可扩展的事件处理系统
Java面试题:设计一个线程安全的单例类并解释其内存占用情况?使用Java多线程工具类实现一个高效的线程池,并解释其背后的原理。结合观察者模式与Java并发框架,设计一个可扩展的事件处理系统
61 1
|
4月前
|
安全 Java 开发者
Java中的并发工具类与线程安全实现
Java中的并发工具类与线程安全实现
|
5月前
|
设计模式 缓存 算法
编写高效的Java工具类:实用技巧与设计模式
编写高效的Java工具类:实用技巧与设计模式
|
4月前
|
设计模式 缓存 算法
编写高效的Java工具类:实用技巧与设计模式
编写高效的Java工具类:实用技巧与设计模式
|
4月前
|
并行计算 Java API
Java中的并发工具类详解
Java中的并发工具类详解