- Qanday ulanish kerak?
- Mening ishimdan misollar: qanday qilib bunday foydali sinf haqida bilmagan holda, men
velosipedtayoqchamni yaratdim. - Keling, men uchun qiziqarli bo'lgan boshqa usullarni ko'rib chiqaylik.
- Keling, xulosa qilaylik.
0. Qanday ulanish kerak
Men bilan qo'l qovushtirib yurganlar Git va Maven bilan ko'proq yoki kamroq tanish, shuning uchun men bu bilimga tayanaman va o'zimni takrorlamayman. Oldingi maqolalarimni o'tkazib yuborgan yoki endigina o'qishni boshlaganlar uchun bu erda Maven va Git haqidagi materiallar mavjud . Albatta, qurish tizimisiz (Maven, Gredl) siz hamma narsani qo'lda ham ulashingiz mumkin, ammo bu bugungi kunda aqldan ozgan va buni qilishning hojati yo'q: hamma narsani qanday qilib to'g'ri qilishni darhol o'rganish yaxshiroqdir. Shuning uchun, Maven bilan ishlash uchun avvalo tegishli bog'liqlikni qo'shamiz:<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>${apache.common.version}</version>
</dependency>
${apache.common.version} bu kutubxonaning versiyasi . Keyin, ba'zi sinfga import qilish uchun import qo'shing:
import org.apache.commons.lang3.StringUtils;
Va bu, hammasi sumkada))
1. Haqiqiy loyihadan misollar
- leftPad usuli
Birinchi misol, umuman olganda, hozir juda ahmoqona ko'rinadi, chunki mening hamkasblarim StringUtils.leftPad haqida bilishi va menga aytgani juda yaxshi. Vazifa nima edi: kod shunday tuzilganki, agar ma'lumotlar to'g'ri kelmasa, uni o'zgartirish kerak edi. Satr maydoni faqat raqamlardan iborat bo'lishi kutilgan edi, ya'ni. agar uning uzunligi 3 bo'lsa va uning qiymati 1 bo'lsa, u holda yozuv "001" bo'lishi kerak. Ya'ni, avval siz barcha bo'shliqlarni olib tashlashingiz kerak, so'ngra uni nol bilan qoplashingiz kerak. Vazifaning mohiyatini aniqroq qilish uchun ko'proq misollar: "12" dan -> "012" dan "1" -> "001" va hokazo. Men nima qildim? Bu LeftPadExample sinfida tasvirlangan . Bularning barchasini bajaradigan usulni yozdim:
public static String ownLeftPad(String value) {
String trimmedValue = value.trim();
if(trimmedValue.length() == value.length()) {
return value;
}
StringBuilder newValue = new StringBuilder(trimmedValue);
IntStream.rangeClosed(1, value.length() - trimmedValue.length())
.forEach(it -> newValue.insert(0, "0"));
return newValue.toString();
}
Asl va qisqartirilgan qiymat o'rtasidagi farqni oddiygina olishimiz va uni oldingi nol bilan to'ldirishimiz mumkin degan fikrni asos qilib oldim. Buni amalga oshirish uchun men IntStream-dan bir xil operatsiyani n marta bajarish uchun foydalandim . Va bu, albatta, sinovdan o'tishi kerak. Agar StringUtils.leftPad usuli haqida oldindan bilganimda nima qila olardim :
public static String apacheCommonLeftPad(String value) {
return StringUtils.leftPad(value.trim(), value.length(), "0");
}
Ko'rib turganingizdek, kod juda kam va hamma tomonidan tasdiqlangan kutubxona ham ishlatiladi. Shu maqsadda men LeftPadExampleTest sinfida ikkita test yaratdim (odatda ular sinfni sinab ko'rishni rejalashtirganda, ular bir xil nomli sinf yaratadilar + Test bir xil paketda, faqat src/test/java da). Ushbu testlar qiymatni to'g'ri o'zgartirishiga ishonch hosil qilish uchun bir usulni, keyin boshqasini tekshiradi. Albatta, ko'proq testlarni yozish kerak bo'ladi, ammo test bizning holatlarimizda asosiy mavzu emas:
package com.github.javarushcommunity.stringutilsdemo;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
@DisplayName("Unit-level testing for LeftPadExample")
class LeftPadExampleTest {
@DisplayName("Should transform by using ownLeftPad method as expected")
@Test
public void shouldTransformOwnLeftPadAsExpected() {
//given
String value = "1 ";
String expectedTransformedValue = "0001";
//when
String transformedValue = LeftPadExample.ownLeftPad(value);
//then
Assertions.assertEquals(expectedTransformedValue, transformedValue);
}
@DisplayName("Should transform by using StringUtils method as expected")
@Test
public void shouldTransformStringUtilsLeftPadAsExpected() {
//given
String value = "1 ";
String expectedTransformedValue = "0001";
//when
String transformedValue = LeftPadExample.apacheCommonLeftPad(value);
//then
Assertions.assertEquals(expectedTransformedValue, transformedValue);
}
}
Hozircha testlar haqida bir nechta sharhlar bera olaman. Ular JUnit 5 yordamida yozilgan:
- Agar test tegishli izohga ega bo'lsa, test sinov sifatida ko'rib chiqiladi - @Test.
- Agar nom testning ishlashini tasvirlash qiyin bo'lsa yoki tavsif uzoq va o'qish uchun noqulay bo'lsa, siz @DisplayName izohini qo'shishingiz va uni testlarni o'tkazishda ko'rinadigan oddiy tavsifga aylantirishingiz mumkin.
- Testlarni yozishda men BDD yondashuvidan foydalanaman, unda testlarni mantiqiy qismlarga ajrataman:
- //berilgan - testdan oldin ma'lumotlarni o'rnatish bloki;
- //biz tekshirayotgan kod qismi ishga tushiriladigan blok qachon;
- //keyin blok bo'lib, unda when blokining natijalari tekshiriladi.
- stripStart usuli
Bu erda men boshida bo'sh joy va vergul bo'lishi mumkin bo'lgan chiziq bilan muammoni hal qilishim kerak edi. Transformatsiyadan keyin ular yangi ma'noga ega bo'lmasligi kerak edi. Muammo bayonoti har qachongidan ham aniqroq. Bir nechta misollar tushunchamizni mustahkamlaydi: “, , kitoblar” -> “kitoblar” “,,, kitoblar” -> “kitoblar” b , kitoblar” -> “b , kitoblar” leftPad bilan bo'lgani kabi, men qo'shdim StrimStartExample klassi , unda ikkita usul mavjud. Biri - o'z yechimi bilan:
public static String ownStripStart(String value) {
int index = 0;
List commaSpace = asList(" ", ",");
for (int i = 0; i < value.length(); i++) {
if (commaSpace.contains(String.valueOf(value.charAt(i)))) {
index++;
} else {
break;
}
}
return value.substring(index);
}
Bu erda bo'sh joy yoki vergul qo'yilmaydigan indeksni topish g'oyasi edi. Agar ular boshida umuman bo'lmagan bo'lsa, unda indeks nolga teng bo'ladi. Va ikkinchisi - StringUtils orqali yechim bilan :
public static String apacheCommonLeftPad(String value) {
return StringUtils.stripStart(value, StringUtils.SPACE + COMMA);
}
Bu erda biz qaysi qator bilan ishlayotganimiz haqidagi birinchi argument ma'lumotlarini, ikkinchisida esa o'tkazib yuborish kerak bo'lgan belgilardan iborat qatorni o'tkazamiz. StripStartExampleTest sinfini xuddi shu tarzda yaratamiz :
package com.github.javarushcommunity.stringutilsdemo;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
@DisplayName("Unit-level testing for StripStartExample")
class StripStartExampleTest {
@DisplayName("Should transform by using stripStart method as expected")
@Test
public void shouldTransformOwnStripStartAsExpected() {
//given
String value = ", , books";
String expectedTransformedValue = "books";
//when
String transformedValue = StripStartExample.ownStripStart(value);
//then
Assertions.assertEquals(expectedTransformedValue, transformedValue);
}
@DisplayName("Should transform by using StringUtils method as expected")
@Test
public void shouldTransformStringUtilsStripStartAsExpected() {
//given
String value = ", , books";
String expectedTransformedValue = "books";
//when
String transformedValue = StripStartExample.apacheCommonLeftPad(value);
//then
Assertions.assertEquals(expectedTransformedValue, transformedValue);
}
}
- isEmpty usuli
Bu usul, albatta, ancha sodda, ammo bu uni kamroq foydali qilmaydi. U String.isEmpty() usulining imkoniyatlarini kengaytiradi , bu esa null uchun chek qo'shadi. Nima uchun? NullPointerException dan qochish uchun, ya'ni null bo'lgan o'zgaruvchida usullarni chaqirmaslik uchun . Shuning uchun, yozmaslik uchun:
if(value != null && value.isEmpty()) {
//doing something
}
Buni oddiygina qilishingiz mumkin:
if(StringUtils.isEmpty(value)) {
//doing something
}
Ushbu usulning afzalligi shundaki, qaysi usuldan foydalanilganligi darhol aniq bo'ladi.
2. StringUtils sinfining boshqa usullarini tahlil qilish
Endi, mening fikrimcha, e'tiborga loyiq bo'lgan usullar haqida gapiraylik. Umuman StringUtils haqida gapiradigan bo'lsak, shuni aytish kerakki, u String sinfida topilganlarga o'xshash null xavfsiz usullarni taqdim etadi ( isEmpty usulida bo'lgani kabi ). Keling, ularni ko'rib chiqaylik:
- solishtirish usuli
Bunday usul String da mavjud va agar ikkita satrni solishtirganda ulardan biri null bo'lsa, NullPointerException ni chiqaradi. Kodimizda xunuk tekshiruvlardan qochish uchun biz StringUtils.compare(String str1, String str2) usulidan foydalanishimiz mumkin : u taqqoslash natijasida intni qaytaradi. Bu qadriyatlar nimani anglatadi? int = 0, agar ular bir xil bo'lsa (yoki ikkalasi ham null bo'lsa). int < 0, agar str1 str2 dan kichik bo'lsa. int > 0, agar str1 str2 dan katta bo'lsa. Bundan tashqari, agar siz ularning hujjatlariga qarasangiz, ushbu usulning Javadoc dasturi quyidagi stsenariylarni taqdim etadi:
StringUtils.compare(null, null) = 0
StringUtils.compare(null , "a") < 0
StringUtils.compare("a", null) > 0
StringUtils.compare("abc", "abc") = 0
StringUtils.compare("a", "b") < 0
StringUtils.compare("b", "a") > 0
StringUtils.compare("a", "B") > 0
StringUtils.compare("ab", "abc") < 0
- ... usullarini o‘z ichiga oladi
Bu erda kommunal dastur ishlab chiquvchilari juda xursand bo'lishdi. Siz xohlagan usul mavjud. Men ularni birlashtirishga qaror qildim:
-
contain - bu kutilgan satrning boshqa satr ichida ekanligini tekshiradigan usul. Bu qanday foydali? Agar matnda ma'lum bir so'z borligiga ishonch hosil qilishingiz kerak bo'lsa, ushbu usuldan foydalanishingiz mumkin.
Misollar:
StringUtils.contains(null, *) = false StringUtils.contains(*, null) = false StringUtils.contains("", "") = true StringUtils.contains("abc", "") = true StringUtils.contains("abc", "a") = true StringUtils.contains("abc", "z") = false
Shunga qaramay, NPE (Null Pointer Exception) xavfsizligi mavjud.
containAny - bu satrda mavjud bo'lgan belgilar mavjudligini tekshiradigan usul. Bundan tashqari, foydali narsa: buni tez-tez qilishingiz kerak. Hujjatlardan misollar:
StringUtils.containsAny(null, *) = false StringUtils.containsAny("", *) = false StringUtils.containsAny(*, null) = false StringUtils.containsAny(*, []) = false StringUtils.containsAny("zzabyycdxx", ['z', 'a']) = true StringUtils.containsAny("zzabyycdxx", ['b', 'y']) = true StringUtils.containsAny("zzabyycdxx", ['z', 'y']) = true StringUtils.containsAny("aba", ['z']) = false
-
containIgnoreCase contain usulining foydali kengaytmasidir . Darhaqiqat, bunday ishni ushbu usulsiz tekshirish uchun siz bir nechta variantlardan o'tishingiz kerak bo'ladi. Va shuning uchun faqat bitta usul uyg'un ravishda qo'llaniladi.
-
containNone - nomiga qarab, siz allaqachon tekshirilayotgan narsani tushunishingiz mumkin. Ichkarida chiziqlar bo'lmasligi kerak. Foydali narsa, albatta. Ba'zi keraksiz belgilarni tezda qidirish;). Telegram botimizda odobsizliklarni filtrlaymiz va bu kulgili usullarni e'tiborsiz qoldirmaymiz.
Va misollar, ularsiz qayerda bo'lar edik:
StringUtils.containsNone(null, *) = true StringUtils.containsNone(*, null) = true StringUtils.containsNone("", *) = true StringUtils.containsNone("ab", '') = true StringUtils.containsNone("abab", 'xyz') = true StringUtils.containsNone("ab1", 'xyz') = true StringUtils.containsNone("abz", 'xyz') = false
Hujjatlardan bir nechta misollar:
StringUtils.containsIgnoreCase(null, *) = false
StringUtils.containsIgnoreCase(*, null) = false
StringUtils.containsIgnoreCase("", "") = true
StringUtils.containsIgnoreCase("abc", "") = true
StringUtils.containsIgnoreCase("abc", "a") = true
StringUtils.containsIgnoreCase("abc", "z") = false
StringUtils.containsIgnoreCase("abc", "A") = true
StringUtils.containsIgnoreCase("abc", "Z") = false
- defaultString usuli
Agar satr null bo'lsa va siz ba'zi bir standart qiymatni o'rnatishingiz kerak bo'lsa, qo'shimcha ma'lumot qo'shmaslikka yordam beradigan bir qator usullar. Har qanday ta'mga mos keladigan ko'plab variantlar mavjud. Ulardan asosiysi StringUtils.defaultString(yakuniy String str, final String defaultStr) - agar str null bo'lsa, biz shunchaki defaultStr qiymatini o'tkazamiz . Hujjatlardan misollar:
StringUtils.defaultString(null, "NULL") = "NULL"
StringUtils.defaultString("", "NULL") = ""
StringUtils.defaultString("bat", "NULL") = "bat"
Ma'lumotlar bilan POJO sinfini yaratishda foydalanish juda qulay.
- deleteWhitespace usuli
Bu qiziqarli usul, garchi uni qo'llashning ko'p variantlari mavjud emas. Shu bilan birga, agar bunday holat yuzaga kelsa, usul, albatta, juda foydali bo'ladi. U satrdagi barcha bo'shliqlarni olib tashlaydi. Bu bo'shliq qayerda bo'lmasin, undan asar ham qolmaydi))) Hujjatlardan misollar:
StringUtils.deleteWhitespace(null) = null
StringUtils.deleteWhitespace("") = ""
StringUtils.deleteWhitespace("abc") = "abc"
StringUtils.deleteWhitespace(" ab c ") = "abc"
- endsWith usuli
O'zi uchun gapiradi. Bu juda foydali usul: u satr tavsiya etilgan satr bilan tugaydimi yoki yo'qligini tekshiradi. Bu ko'pincha kerak. Albatta, siz chekni o'zingiz yozishingiz mumkin, ammo tayyor usuldan foydalanish yanada qulayroq va yaxshiroq. Misollar:
StringUtils.endsWith(null, null) = true
StringUtils.endsWith(null, "def") = false
StringUtils.endsWith("abcdef", null) = false
StringUtils.endsWith("abcdef", "def") = true
StringUtils.endsWith("ABCDEF", "def") = false
StringUtils.endsWith("ABCDEF", "cde") = false
StringUtils.endsWith("ABCDEF", "") = true
Ko'rib turganingizdek, hamma narsa bo'sh satr bilan tugaydi))) Menimcha, bu misol (StringUtils.endsWith("ABCDEF", "") = rost) shunchaki bonus, chunki bu bema'nilik) Yana bir usul bor holatga e'tibor bermaydi.
- teng usuli
Ikki qatorni taqqoslaydigan null xavfsiz usulning ajoyib namunasi. U erga nima qo'ysak, javob o'sha erda bo'ladi va u xatosiz bo'ladi. Misollar:
StringUtils.equals(null, null) = true
StringUtils.equals(null, "abc") = false
StringUtils.equals("abc", null) = false
StringUtils.equals("abc", "abc") = true
StringUtils.equals("abc", "ABC") = false
Albatta, equalsIgnoreCase ham mavjud - hamma narsa xuddi shu tarzda amalga oshiriladi, faqat biz ishni e'tiborsiz qoldiramiz. Ko'raylikchi?
StringUtils.equalsIgnoreCase(null, null) = true
StringUtils.equalsIgnoreCase(null, "abc") = false
StringUtils.equalsIgnoreCase("abc", null) = false
StringUtils.equalsIgnoreCase("abc", "abc") = true
StringUtils.equalsIgnoreCase("abc", "ABC") = true
- teng har qanday usul
Keling, tenglash usulini kengaytiramiz . Aytaylik, bir nechta tenglikni tekshirish o'rniga biz bittasini o'tkazmoqchimiz. Buning uchun biz satrlar to'plamini solishtiradigan satrni o'tkazishimiz mumkin, agar ulardan birontasi taklif qilinganiga teng bo'lsa, u TRUE bo'ladi. Biz ularni bir-biri bilan solishtirish uchun satr va satrlar to'plamini o'tkazamiz (to'plamdagi satrlar bilan birinchi qator). Qiyinmi? Bu erda nima nazarda tutilganini tushunishga yordam beradigan hujjatlardan misollar:
StringUtils.equalsAny(null, (CharSequence[]) null) = false
StringUtils.equalsAny(null, null, null) = true
StringUtils.equalsAny(null, "abc", "def") = false
StringUtils.equalsAny("abc", null, "def") = false
StringUtils.equalsAny("abc", "abc", "def") = true
StringUtils.equalsAny("abc", "ABC", "DEF") = false
Shuningdek, equalsAnyIgnoreCase mavjud . Va bunga misollar:
StringUtils.equalsAnyIgnoreCase(null, (CharSequence[]) null) = false
StringUtils.equalsAnyIgnoreCase(null, null, null) = true
StringUtils.equalsAnyIgnoreCase(null, "abc", "def") = false
StringUtils.equalsAnyIgnoreCase("abc", null, "def") = false
StringUtils.equalsAnyIgnoreCase("abc", "abc", "def") = true
StringUtils.equalsAnyIgnoreCase("abc", "ABC", "DEF") = true
GO TO FULL VERSION