日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

String.split()方法你可能不知道的一面

發(fā)布時間:2025/3/14 编程问答 41 豆豆
生活随笔 收集整理的這篇文章主要介紹了 String.split()方法你可能不知道的一面 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

  String.split()方法你可能不知道的一面
  一、問題
  java中String的split()是我們經(jīng)常使用的方法,用來按照特定字符分割字符串,那么我們看以下一段代碼:
  public void splitTest() {
  String str = "aaa|bbb|ccc";
  String[] array = str.split("|");
  System.out.println(Arrays.toString(array));
  }
  是不是感覺很簡單,就是吧str按照"|"分割,結(jié)果就是[aaa,bbb,ccc]嘛。如果你這么想,那么以后在用這個方法時你可能會犯下大錯,把程序跑起來,你會驚訝的發(fā)現(xiàn)程序輸入如下結(jié)果:
  [, a, a, a, |, b, b, b, |, c, c, c]
  為什么會出現(xiàn)這種情況呢?我們再來運行一下str.split("");就會發(fā)現(xiàn)結(jié)果和之前的結(jié)果一樣,也就是說我們使用"|"分割的時候其實split是按照空字符分割的。
  二、探究
  為了找到原因,我們在來使用其他幾種字符測試一下,結(jié)果如下:
  0:[aaa, bbb, ccc]
  $:[aaa$bbb$ccc]
  ,:[aaa, bbb, ccc]
  *:異常java.util.regex.PatternSyntaxException: Dangling meta character '*' near index 0
  ^:[aaa^bbb^ccc]
  我們會發(fā)現(xiàn)對于數(shù)字,","結(jié)果是正確的,而對于特殊字符,結(jié)果都不正確,而且如果經(jīng)驗豐富,你可能已經(jīng)發(fā)現(xiàn),這些特殊字符都是正則表達式中的匹配符,而那個異常也很明確的說明了這一點。
  因此,我們可以猜測在split內(nèi)部使用了正則表達式來匹配并分割字符串。那么現(xiàn)在又有一個疑問:我們知道一般情況下String涉及的字符串處理多數(shù)使用indexOf()(可能是考慮效率問題吧),那么這里為什么使用正則呢?我們還是直接看看源碼吧:
  public String[] split(String regex, int limit) {
  char ch = 0;
  if (((regex.value.length == 1 &&
  ".$|()[{^?*+\\".indexOf(ch = regex.charAt(0)) == -1) ||
  (regex.length() == 2 &&
  regex.charAt(0) == '\\' &&
  (((ch = regex.charAt(1))-'0')|('9'-ch)) < 0 &&
  ((ch-'a')|('z'-ch)) < 0 &&
  ((ch-'A')|('Z'-ch)) < 0)) &&
  (ch < Character.MIN_HIGH_SURROGATE ||
  ch > Character.MAX_LOW_SURROGATE))
  {
  int off = 0;
  int next = 0;
  boolean limited = limit > 0;
  ArrayList<String> list = new ArrayList<>();
  while ((next = indexOf(ch, off)) != -1) {
  if (!limited || list.size() < limit - 1) {
  list.add(substring(off, next));
  off = next + 1;
  } else { // last one
  //assert (list.size() == limit - 1);
  list.add(substring(off, value.length));
  off = value.length;
  break;
  }
  }
  // If no match was found, return this
  if (off == 0)
  return new String[]{this};
  // Add remaining segment
  if (!limited || list.size() < limit)
  list.add(substring(off, value.length));
  // Construct result
  int resultSize = list.size();
  if (limit == 0)
  while (resultSize > 0 && list.get(resultSize - 1)。length() == 0)
  resultSize--;
  String[] result = new String[resultSize];
  return list.subList(0, resultSize)。toArray(result);
  }
  return Pattern.compile(regex)。split(this, limit);
  }
  可以看到方法內(nèi)有一個if,如果條件為true,那么就使用indexOf()判斷后substring()截取,如果為false,則使用正則處理。那么我們就來分析下這個if的條件:
  //第一步部分:當regex的長度為1且不是".$|()[{^?*+\\"中的時,為真
  (regex.value.length == 1 &&".$|()[{^?*+\\".indexOf(ch = regex.charAt(0)) == -1)
  //第二部分:當長度為2時且第一個字符為"\"轉(zhuǎn)義字符,第二個字符不是字符0-9 a-z A-Z 以及utf-16之間的字符
  (regex.length() == 2 && regex.charAt(0) == '\\' && (((
  ch = regex.charAt(1))-'0')|('9'-ch)) < 0 &&
  ((ch-'a')|('z'-ch)) < 0 &&
  ((ch-'A')|('Z'-ch)) < 0)) &&
  (ch < Character.MIN_HIGH_SURROGATE ||
  ch > Character.MAX_LOW_SURROGATE) www.tygj123.com
  從if可以看出如果regex內(nèi)容為一個非正則匹配符或者是轉(zhuǎn)以后的特殊字符時,采用indexOf()+substring()處理,否則使用正則表達式。
  那么為什么這么做呢,直接使用第一種方法不就行了?其實我們可以考慮一種復(fù)雜的情況:
  aaax111xbbbx222xcccx333xddd
  如果我想分割出這樣的結(jié)果 [aaa, bbb, ccc, ddd] 應(yīng)該則么做呢?按照第一種方法,實現(xiàn)起來很麻煩,需要一大堆判斷,反而不如正則方便,而String中的split()方法正是出于這樣的考慮實現(xiàn)的,不信你用split("x.*?x")試試。
  三、啟示
  這次這件事雖小,但是卻讓我收獲不少。
  1、使用一個不了解的方法前,一定要看一眼提示,split方法說明里雖然沒有明確的提示上述問題,但是多個地方都提到了正則,連參數(shù)名字都是regex,作為一個經(jīng)驗豐富的程序員,應(yīng)該想到這一點。
  2、對于一些小的功能點(往往我們還胸有成竹)一定要寫個Test測一下,其實把代碼貼過去跑一下費不了多少勁,但是當他淹沒在成百上千行的代碼中時,想要在發(fā)現(xiàn)問題就很費勁了,特別是你不調(diào)試根本想不到這點會錯 www.yztrans.com
  3、我們在多數(shù)項目中都要建個util工具包,封裝各種輔助的操作類,然而這些類的功能往往只是滿足當時的需求,之后用到類似但有變動的功能時往往習(xí)慣單獨實現(xiàn)一個,而不是實現(xiàn)一個完善的覆蓋原來的,從設(shè)計的角度會造成接口不一致:明明同樣的需求、同樣的參數(shù),我卻還要看看他的內(nèi)部實現(xiàn)才能選擇用哪個。對于這些工具類,我們不一定要非常完美,但是應(yīng)該用心做到盡量完善,這也方便復(fù)用。

轉(zhuǎn)載于:https://www.cnblogs.com/haosola/p/3655733.html

總結(jié)

以上是生活随笔為你收集整理的String.split()方法你可能不知道的一面的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。