常用工具類

来源:https://www.cnblogs.com/doug-shaw/archive/2022/11/27/java-utility-classes.html
-Advertisement-
Play Games

Apache-Commons-* 字元串 判斷字元串是否為空白字元串 以前判斷字元串是否為空: if ((name == null) || (name.isEmpty())){} 使用 apache-common-lang3 的 StringUtils: void testIsBlank() { / ...


Apache-Commons-*

字元串

判斷字元串是否為空白字元串

以前判斷字元串是否為空:

if ((name == null) || (name.isEmpty())){}

使用 apache-common-lang3StringUtils

void testIsBlank() {
   // true
   Assertions.assertTrue(StringUtils.isBlank(" "));

   // true
   Assertions.assertTrue(StringUtils.isBlank(""));

   // true
   Assertions.assertTrue(StringUtils.isBlank(null));

   // false
   Assertions.assertFalse(StringUtils.isBlank("foo"));

   // true
   Assertions.assertTrue(StringUtils.isAnyBlank(null, " "));

   // false
   Assertions.assertFalse(StringUtils.isAnyBlank("foo", " bar "));
}
左邊填充字元串

有時候我們需要生成流水號,例如4位數的流水號,從1開始其餘用字元'0'填充,就可以使用 leftPad 方法,示例如下:

@Test
void testLeftPad() {
   // 0001
   Assertions.assertEquals("0001", StringUtils.leftPad("1", 4, '0'));
}
右邊填充字元串
@Test
void testRightPad() {
   // 1000
   Assertions.assertEquals("1000", StringUtils.rightPad("1", 4, '0'));
}
分割字元串
// ["a","b","c"]
Assertions.assertEquals(Arrays.toString(new String[]{"a", "b", "c"}), Arrays.toString(StringUtils.split("a,b,c", ",")));
字元串比較
// true
Assertions.assertTrue(StringUtils.equals(null, null));

// false
Assertions.assertFalse(StringUtils.equals("null", null));
字元串已指定子字元串開頭
@Test
void testStartWith() {
   // true
   Assertions.assertTrue(StringUtils.startsWith("hello,world", "hello"));

   // false
   Assertions.assertFalse(StringUtils.startsWith("你好,世界", "世界"));
}

數值工具類

轉換為 int 類型

將字元串轉換為 int 類型,toInt(String str) 在轉換失敗的時候會返回預設值 0,如果需要指定預設值那麼可以使用 toInt(final String str, final int defaultValue)

@Test
void testToInt() {
   // 0
   Assertions.assertEquals(0, NumberUtils.toInt("abc"));

   // 0
   Assertions.assertEquals(0, NumberUtils.toInt("01c"));

   // 0
   Assertions.assertEquals(0, NumberUtils.toInt("1a3"));

   // 1
   Assertions.assertEquals(1, NumberUtils.toInt("foo", 1));

   // 11
   Assertions.assertEquals(11, NumberUtils.toInt("11"));

   // 11
   Assertions.assertEquals(11, NumberUtils.toInt("011", 3));
}

數組

判斷數組是否為空
@Test
void testIsEmpty() {
   // true
   Assertions.assertTrue(ArrayUtils.isEmpty(new Object[]{}));

   // false
   Assertions.assertFalse(ArrayUtils.isEmpty(new String[]{"foo"}));
}

日期

增加指定天數

除了增加指定的天數,common-lang3 還提供了:

  1. addHours:增加指定小時
  2. addMonths:增加指定月數
  3. 等...
@Test
void testAddDay() {
   Date now = new Date();
   Date tomorrow = DateUtils.addDays(now, 1);

   Assertions.assertEquals(1, Duration.ofMillis(tomorrow.getTime() - now.getTime()).toDays());
   Assertions.assertEquals(Duration.ofDays(1).toMillis(), Duration.ofMillis(tomorrow.getTime() - now.getTime()).toMillis());
}
格式化日期
tring pattern = "yyyy-MM-dd HH:mm:ss";
Date d1 = DateUtils.parseDate("2022-10-22 00:00:00", pattern);

Assertions.assertEquals("2022-10-22 00:00:00", DateFormatUtils.format(d1, pattern));
判斷是否為同一天
String parsePattern = "yyyy-MM-dd HH:mm:ss";
Date d1 = DateUtils.parseDate("2022-10-22 00:00:00", parsePattern);
Date d2 = DateUtils.parseDate("2022-10-22 23:59:59", parsePattern);
// true
Assertions.assertTrue(DateUtils.isSameDay(d1, d2));

d1 = DateUtils.parseDate("2022-10-23 00:00:00", parsePattern);
d2 = DateUtils.parseDate("2022-10-22 00:00:00", parsePattern);
// false
Assertions.assertFalse(DateUtils.isSameDay(d1, d2));

枚舉

@Test
void testGetEnum() {
   Assertions.assertThrowsExactly(IllegalArgumentException.class, () -> Season.valueOf("Spring"));

   // 預設返回null,不拋出異常
   Assertions.assertNull(EnumUtils.getEnum(Season.class, "spring"));
   // 指定預設值
   Assertions.assertEquals(Season.SPRING, EnumUtils.getEnumIgnoreCase(Season.class, "spring"));
   // 忽略大小寫匹配
   Assertions.assertEquals(Season.SPRING, EnumUtils.getEnum(Season.class, "spring", Season.SPRING));
}

enum Season {
   SPRING,
}

Guava

分割字元串

在瞭解 Guava 提供的字元串分割器之前,我們先來看看 Java 提供的字元串分隔有什麼缺點,如下所示,輸出的結果為:

",a,,b,".split(",")
  1. "", "a", "", "b", ""
  2. null, "a", null, "b", null
  3. "a", null, "b"
  4. "a", "b"
  5. 以上都不對

正確輸出結果是 [, a, , b],答案是選項5:“以上都不對”。Splitter 不僅實現了字元串分隔,還提供了對應的修飾符,即對拆分結果進行處理,例如:

String str = "foo, bar ,,,baz";
// ["foo","bar","baz"]
Splitter.on(",")
      .trimResults()
      .omitEmptyStrings()
      .splitToList(str);

// [上下上下左, 左, 右右]
str = "baba上下上下左a左b右右";
res = Splitter.on(CharMatcher.inRange('a', 'b'))
      .trimResults()
      .omitEmptyStrings()
      .splitToList(str);
// [上下上下左, 左, 右右]      
log.info("{}", res);
拆分器工廠
方法 描述 示例
Splitter.on(char) 按單個字元拆分 Splitter.on(',');
Splitter.on(CharMatcher) 按字元匹配器拆分 Splitter.on(CharMatcher.inRange('a', 'b'))
Splitter.on(String) 按字元串拆分 Splitter.on(", ")
Splitter.on(Pattern)或onPattern(String) 按正則表達式拆分 Splitter.on("\r?\n ")
Splitter.fixedLength(int) 按固定長度拆分;最後一段可能比給定長度短,但不會為空。 Splitter.fixedLength(3)
拆分器修飾符
方法 描述
omitEmptyStrings() 從結果中自動忽略空白字元串
trimResults() 移除結果字元串的首位空白字元
trimResults(CharMatcher) 給定匹配器,移除結果字元串的首位匹配字元
limit(int) 限制拆分出的字元串數量

不可變集合

public static final ImmutableSet<String> COLOR_NAMES = ImmutableSet.of(
        "red",
        "orange",
        "yellow",
        "green",
        "blue",
        "purple");

class Foo {
    Set<Bar> bars;
    Foo(Set<Bar> bars) {
        this.bars = ImmutableSet.copyOf(bars); // defensive copy!
    }
}

不可變對象有很多的優點:

  1. 當對象被不可信的庫調用時,不可變形式是安全的;
  2. 不可變對象被多個線程調用時,不存在競態條件問題
  3. 不可變集合不需要考慮變化,因此可以節省時間和空間。所有不可變的集合都比它們的可變形式有更好的記憶體利用率(分析和測試細節);
  4. 不可變對象因為有固定不變,可以作為常量來安全使用。
使用不可變集合

不可變集合可以用如下多種方式創建:

  1. copyOfImmutableList.copyOf
  2. ofImmutableList.of("a","b","c")
  3. Builder 工具,例如:
public static final ImmutableSet<Color> GOOGLE_COLORS =
        ImmutableSet.<Color>builder()
            .addAll(WEBSAFE_COLORS)
            .add(new Color(0, 191, 255))
            .build();

連接字元串

@Test
void testJoin() {
   // foo,bar
   Assertions.assertEquals("foo,bar", Joiner.on(',').join(ImmutableList.of("foo", "bar")));

   // foo
   Assertions.assertEquals("foo", Joiner.on(',').skipNulls().join("foo", null));

   // foo,empty
   Assertions.assertEquals("foo,empty", Joiner.on(',').useForNull("empty").join("foo", null));


   // 拋出空指針異常
   Assertions.assertThrowsExactly(NullPointerException.class, () -> Joiner.on(',').join("foo", null));
}

警告:joiner實例總是不可變的。用來定義joiner目標語義的配置方法總會返回一個新的joiner實例。這使得joiner實例都是線程安全的,你可以將其定義為static final常量。

Strings

null 轉換為空字元串:

Assertions.assertEquals("", Strings.nullToEmpty(null));

將空字元串轉換為 null

Assertions.assertEquals(null, Strings.emptyToNull(""));
Assertions.assertEquals(null, Strings.emptyToNull(null));

CharMatcher

String noControl = CharMatcher.JAVA_ISO_CONTROL.removeFrom(string); //移除control字元
String theDigits = CharMatcher.DIGIT.retainFrom(string); //只保留數字字元
String spaced = CharMatcher.WHITESPACE.trimAndCollapseFrom(string, ' ');
//去除兩端的空格,並把中間的連續空格替換成單個空格
String noDigits = CharMatcher.JAVA_DIGIT.replaceFrom(string, "*"); //用*號替換所有數字
String lowerAndDigit = CharMatcher.JAVA_DIGIT.or(CharMatcher.JAVA_LOWER_CASE).retainFrom(string);
// 只保留數字和小寫字母

Spring

判斷集合是否為空

@Test
void testIsEmpty() {
   Assertions.assertTrue(CollectionUtils.isEmpty((List<?>) null));
   Assertions.assertTrue(CollectionUtils.isEmpty((Set<?>) null));
   Assertions.assertTrue(CollectionUtils.isEmpty((Map<?, ?>) null));

   Assertions.assertTrue(CollectionUtils.isEmpty(Collections.emptyList()));
   Assertions.assertTrue(CollectionUtils.isEmpty(Collections.emptySet()));
   Assertions.assertTrue(CollectionUtils.isEmpty(Collections.emptyMap()));

   Assertions.assertTrue(CollectionUtils.isEmpty(List.of()));
   Assertions.assertTrue(CollectionUtils.isEmpty(Set.of()));
   Assertions.assertTrue(CollectionUtils.isEmpty(Map.of()));

   List<Object> list = new LinkedList<>();
   list.add(new Object());
   Assertions.assertFalse(CollectionUtils.isEmpty(list));
   Assertions.assertFalse(CollectionUtils.isEmpty(List.of("foo")));

   Map<String, String> map = new HashMap<>();
   map.put("foo", "bar");
   Assertions.assertFalse(CollectionUtils.isEmpty(map));
   Assertions.assertFalse(CollectionUtils.isEmpty(Map.of("foo", "bar")));
}

獲取集合的第一個元素

@Test
void testFirstElement() {
   Assertions.assertNull(CollectionUtils.firstElement((Set<?>) null));
   Assertions.assertNull(CollectionUtils.firstElement((List<?>) null));

   List<String> list = new ArrayList<>();
   list.add(null);
   // null
   Assertions.assertNull(CollectionUtils.firstElement(list));

   list = new ArrayList<>();
   list.add("foo");
   // foo
   Assertions.assertEquals("foo", CollectionUtils.firstElement(list));

   list = List.of("foo", "bar");
   // foo
   Assertions.assertEquals("foo", CollectionUtils.firstElement(list));


   Set<String> set = new TreeSet<>();
   set.add("b");
   set.add("a");
   // a
   Assertions.assertEquals("a", CollectionUtils.firstElement(set));

   // b
   set = new TreeSet<>(Comparator.reverseOrder());
   set.add("b");
   set.add("a");
   Assertions.assertEquals("b", CollectionUtils.firstElement(set));
}

獲取集合的最後一個元素

@Test
void testLastElement() {
   Assertions.assertNull(CollectionUtils.lastElement((Set<?>) null));
   Assertions.assertNull(CollectionUtils.lastElement((List<?>) null));

   List<String> list = new ArrayList<>();
   list.add(null);
   Assertions.assertNull(CollectionUtils.lastElement(list));

   list = new ArrayList<>();
   list.add("foo");
   list.add("bar");
   // bar
   Assertions.assertEquals("bar", CollectionUtils.lastElement(list));

   list = List.of("foo", "bar");
   Assertions.assertEquals("bar", CollectionUtils.lastElement(list));

   Set<String> set = new TreeSet<>();
   set.add("b");
   set.add("a");
   // b
   Assertions.assertEquals("b", CollectionUtils.lastElement(set));

   set = new TreeSet<>(Comparator.reverseOrder());
   set.add("b");
   set.add("a");
   // a
   Assertions.assertEquals("a", CollectionUtils.lastElement(set));
}

對象屬性拷貝

添加一個測試對象:

class User {
   private String name;
   private String email;
   
   // 忽略getXxx和setXxx方法
@Test
void testCopyProperties() {
   User user =  new User();
         user.setName("foo");
         user.setEmail("bar");

   User target = new User();
    
   // 拷貝屬性
   BeanUtils.copyProperties(user, target, "email");

   Assertions.assertEquals("foo", target.getName());
   Assertions.assertNull(target.getEmail());
}

命名的 ThreadLocal

@Test
void testNamedThreadLocal() {
   NamedThreadLocal<String> threadLocal = new NamedThreadLocal<>("task");
   Assertions.assertEquals("task", threadLocal.toString());
}

判斷對象是否相等

@Test
void testNullSafeEquals() {
   Assertions.assertTrue(ObjectUtils.nullSafeEquals(null, null));
   Assertions.assertTrue(ObjectUtils.nullSafeEquals("a", "a"));
   Assertions.assertTrue(ObjectUtils.nullSafeEquals(Optional.of("a"), Optional.of("a")));
}

判斷對象是否為空

@Test
void testIsEmpty() {
   Assertions.assertTrue(ObjectUtils.isEmpty((Object) null));
   Assertions.assertTrue(ObjectUtils.isEmpty(Optional.empty()));
   Assertions.assertTrue(ObjectUtils.isEmpty(""));
   Assertions.assertTrue(ObjectUtils.isEmpty(new String[]{}));
   Assertions.assertTrue(ObjectUtils.isEmpty(Collections.emptyList()));
   Assertions.assertTrue(ObjectUtils.isEmpty(Collections.emptyMap()));
}

資源工具類

有時候我們需要載入 classpath 目錄下的資源,例如:

File file = new File(ResourceUtilsTests.class.getClassLoader().getResource("log4j2.xml").toURI());
Assertions.assertEquals("log4j2.xml", file.getName());

使用 SpringResourceUtils 只需要這麼寫:

File file = ResourceUtils.getFile(ResourceUtils.CLASSPATH_URL_PREFIX + "log4j2.xml");
Assertions.assertEquals("log4j2.xml", file.getName());

計時器

@Test
void testStopWatch() throws InterruptedException {
   // 創建一個計時器(秒錶)
   StopWatch stopWatch = new StopWatch();
   // 開始計時
   stopWatch.start();
   Thread.sleep(Duration.ofSeconds(1).toMillis());
   // 停止計時
   stopWatch.stop();
   // 獲取總耗時(毫秒)
   // 1005ms.
   log.info("{}ms.", stopWatch.getTotalTimeMillis());
   // 1s.
   log.info("{}s.", Duration.ofMillis(stopWatch.getTotalTimeMillis()).toSeconds());
}

UriComponentsBuilder

有時候我們需要在服務端手動發送請求,在請求 url 我們使用字元串拼接的方式,Spring 提供了UriComponentsBuilder 能讓我們更加語意化來構建一個請求url,而且還會自動對url進行編碼:

@Test
void testFromUriString() {
   String uri = UriComponentsBuilder
         .fromUriString("/coffee/{foo}/{id}/like")
         .build("aa", "bb")
         .toString();
   Assertions.assertEquals("/coffee/aa/bb/like", uri);

   uri = UriComponentsBuilder
         .fromUriString("http://localhost:8080/coffe/{id}")
         .encode()
         .build(1).toString();
   Assertions.assertEquals("http://localhost:8080/coffe/1", uri);

   uri = UriComponentsBuilder
         .fromUriString("http://localhost:8080/coffee?name={name}")
         .build(" ").toString();
   Assertions.assertEquals("http://localhost:8080/coffee?name=%20",uri);
}

hutool

校驗

@Test
void testIsCitizenId() {
   // 校驗是否為身份證
   Assertions.assertTrue(Validator.isCitizenId("110101199003074477"));

   // 15位身份證號碼驗證
   Assertions.assertTrue(Validator.isCitizenId("410001910101123"));

   // 10位身份證號碼驗證
   Assertions.assertTrue(Validator.isCitizenId("U193683453"));
}

@Test
void testIsMobile() {
   // 校驗是否為手機號
   Assertions.assertTrue(Validator.isMobile("13900221432"));
   Assertions.assertTrue(Validator.isMobile("015100221432"));
   Assertions.assertTrue(Validator.isMobile("+8618600221432"));
}

@Test
void testIsPlateNumber() {
   // 校驗是否為車牌號
   Assertions.assertTrue(Validator.isPlateNumber("粵BA03205"));
   Assertions.assertTrue(Validator.isPlateNumber("閩20401領"));
}

emoji

@Test
void testToUnicode() {
   String unicode = EmojiUtil.toUnicode(":smile:");
   Assertions.assertEquals("

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 一:背景 1.講故事 前段時間分析了一個dump,一頓操作之後,我希望用外力來阻止程式內部對某一個com組件的調用,對,就是想藉助外力實現,如果用 windbg 的話,可以說非常輕鬆,但現實情況比較複雜,客戶機沒有windbg,也不想加入任何的手工配置,希望全自動化來處理。 真的很無理哈。。。不過這 ...
  • 大家好,我是痞子衡,是正經搞技術的痞子。今天痞子衡給大家分享的是MCUXpresso IDE下高度靈活的FreeMarker鏈接文件模板機制。 痞子衡之前寫過一篇文章 《MCUXpresso IDE下工程鏈接文件配置管理與自動生成機制》,這篇文章介紹了 MCUXpresso IDE 在鏈接文件管理設 ...
  • Multipass 是由Ubuntu官方提供,在Linux,MacOS和Windows上快速生成Ubuntu虛擬機的工具。它提供了一個簡單但功能強大的CLI,可讓我們在本地快速進入Ubuntu系統環境並使用Linux命令,亦可以在本地電腦創建自己的迷你型雲伺服器。總的來說就是在本地創建Ubuntu... ...
  • 一 引言 前段時間自己實現了ansible對接操作系統升級腳本,現將整個項目記錄如下,如果項目中存在問題或優化的點,請幫忙指正。本項目運行在RedHat Linux系統。 在我們生產環境中,操作系統的升級由系統升級、伺服器重啟以及vmtools安裝三部分組成。本次項目的目標有兩點: (1) ansi ...
  • 摘要:近日,經過全球知名獨立認證機構SGS Brightsight實驗室的安全評估,華為雲GaussDB企業級分散式資料庫內核獲得全球權威信息技術安全性評估標準CC EAL4+級別認證 本文分享自華為雲社區《國內唯一!GaussDB拿下的安全認證CC EAL4+究竟有多難?》,作者:GaussDB ...
  • # HTTPS server server { listen 443; server_name ************.com; ssl on; ssl_certificate cert/************.com.pem; ssl_certificate_key cert/******** ...
  • 一、數據類型存儲 在JavaScript中存在兩大數據類型:基本類型、引用類型。 基本數據類型存放在棧中,是一段簡單的數據段,數據大小確定,記憶體空間大小可以分配,是直接按值存放的,可以按值訪問。 引用數據類型存放在堆中,變數在棧中保存的是指向堆記憶體的地址值,這個地址值指向對應的對象類型,訪問堆記憶體中 ...
  • 摘要:在競爭如此激烈的當下,作為一名IT新人,怎麼才能讓HR眼前一亮,從萬千簡歷中脫穎而出成為最亮的那個崽呢? 本文分享自華為雲社區《【一行代碼秒上雲】連夜自建網站背刺我的求職對手們 !》,作者:AppCloud小助手。 前言 在競爭如此激烈的當下,作為一名IT新人,怎麼才能讓HR眼前一亮,從萬千簡 ...
一周排行
    -Advertisement-
    Play Games
  • Timer是什麼 Timer 是一種用於創建定期粒度行為的機制。 與標準的 .NET System.Threading.Timer 類相似,Orleans 的 Timer 允許在一段時間後執行特定的操作,或者在特定的時間間隔內重覆執行操作。 它在分散式系統中具有重要作用,特別是在處理需要周期性執行的 ...
  • 前言 相信很多做WPF開發的小伙伴都遇到過表格類的需求,雖然現有的Grid控制項也能實現,但是使用起來的體驗感並不好,比如要實現一個Excel中的表格效果,估計你能想到的第一個方法就是套Border控制項,用這種方法你需要控制每個Border的邊框,並且在一堆Bordr中找到Grid.Row,Grid. ...
  • .NET C#程式啟動閃退,目錄導致的問題 這是第2次踩這個坑了,很小的編程細節,容易忽略,所以寫個博客,分享給大家。 1.第一次坑:是windows 系統把程式運行成服務,找不到配置文件,原因是以服務運行它的工作目錄是在C:\Windows\System32 2.本次坑:WPF桌面程式通過註冊表設 ...
  • 在分散式系統中,數據的持久化是至關重要的一環。 Orleans 7 引入了強大的持久化功能,使得在分散式環境下管理數據變得更加輕鬆和可靠。 本文將介紹什麼是 Orleans 7 的持久化,如何設置它以及相應的代碼示例。 什麼是 Orleans 7 的持久化? Orleans 7 的持久化是指將 Or ...
  • 前言 .NET Feature Management 是一個用於管理應用程式功能的庫,它可以幫助開發人員在應用程式中輕鬆地添加、移除和管理功能。使用 Feature Management,開發人員可以根據不同用戶、環境或其他條件來動態地控制應用程式中的功能。這使得開發人員可以更靈活地管理應用程式的功 ...
  • 在 WPF 應用程式中,拖放操作是實現用戶交互的重要組成部分。通過拖放操作,用戶可以輕鬆地將數據從一個位置移動到另一個位置,或者將控制項從一個容器移動到另一個容器。然而,WPF 中預設的拖放操作可能並不是那麼好用。為瞭解決這個問題,我們可以自定義一個 Panel 來實現更簡單的拖拽操作。 自定義 Pa ...
  • 在實際使用中,由於涉及到不同編程語言之間互相調用,導致C++ 中的OpenCV與C#中的OpenCvSharp 圖像數據在不同編程語言之間難以有效傳遞。在本文中我們將結合OpenCvSharp源碼實現原理,探究兩種數據之間的通信方式。 ...
  • 一、前言 這是一篇搭建許可權管理系統的系列文章。 隨著網路的發展,信息安全對應任何企業來說都越發的重要,而本系列文章將和大家一起一步一步搭建一個全新的許可權管理系統。 說明:由於搭建一個全新的項目過於繁瑣,所有作者將挑選核心代碼和核心思路進行分享。 二、技術選擇 三、開始設計 1、自主搭建vue前端和. ...
  • Csharper中的表達式樹 這節課來瞭解一下表示式樹是什麼? 在C#中,表達式樹是一種數據結構,它可以表示一些代碼塊,如Lambda表達式或查詢表達式。表達式樹使你能夠查看和操作數據,就像你可以查看和操作代碼一樣。它們通常用於創建動態查詢和解析表達式。 一、認識表達式樹 為什麼要這樣說?它和委托有 ...
  • 在使用Django等框架來操作MySQL時,實際上底層還是通過Python來操作的,首先需要安裝一個驅動程式,在Python3中,驅動程式有多種選擇,比如有pymysql以及mysqlclient等。使用pip命令安裝mysqlclient失敗應如何解決? 安裝的python版本說明 機器同時安裝了 ...