- Қалай қосылуға болады?
- Менің жұмысымнан мысалдар: мен осындай пайдалы сынып туралы білмей,
велосипедбалдағын қалай жасадым. - Маған қызықты деп тапқан басқа әдістерді қарастырайық.
- Қорытындылайық.
0. Қосылу жолы
Менімен қол ұстасып жүргендер Гитпен де, Мавенмен де азды-көпті таныс, сондықтан мен бұл білімге сүйенемін және өзімді қайталамаймын. Менің алдыңғы мақалаларымды жіберіп алған немесе оқуды енді бастағандар үшін мұнда Maven және Git туралы материалдар бар . Әрине, құрастыру жүйесі жоқ (Maven, Gredl) сіз бәрін қолмен қоса аласыз, бірақ бұл қазіргі уақытта ақылсыз және мұны істеудің қажеті жоқ: бәрін қалай дұрыс жасау керектігін бірден үйренгеніңіз жөн. Сондықтан, Maven-пен жұмыс істеу үшін алдымен сәйкес тәуелділікті қосамыз:<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>${apache.common.version}</version>
</dependency>
Мұндағы ${apache.common.version} - осы кітапхананың нұсқасы. Әрі қарай, кейбір сыныпта импорттау үшін импортты қосыңыз:
import org.apache.commons.lang3.StringUtils;
Міне, бәрі сөмкеде))
1. Нақты жобадан мысалдар
- leftPad әдісі
Бірінші мысал әдетте ақымақ болып көрінеді, сондықтан әріптестерімнің StringUtils.leftPad туралы білгені және маған айтқаны өте жақсы. Тапсырма қандай болды: code егер ол дұрыс келмесе, деректерді түрлендіру қажет болатындай етіп жасалған. Жол өрісі тек сандардан тұруы керек деп күтілді, яғни. егер оның ұзындығы 3 болса және оның мәні 1 болса, онда жазба «001» болуы керек. Яғни, алдымен барлық бос орындарды алып тастау керек, содан кейін оны нөлдермен жабу керек. Тапсырманың мәнін түсіндіру үшін көбірек мысалдар: «12» -> «012» «1» -> «001» және т.б. Мен не істедім? Бұл LeftPadExample сыныбында сипатталған . Мен мұның бәрін жасайтын әдісті жаздым:
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();
}
Негізінде мен бастапқы мен кесілген мәннің арасындағы айырмашылықты алып, оны алдына нөлдермен толтыра аламыз деген идеяны алдым. Бұл әрекетті орындау үшін мен IntStream қызметін n рет бірдей әрекетті орындау үшін қолдандым. Және бұл міндетті түрде сынақтан өтуі керек. Егер мен StringUtils.leftPad әдісі туралы алдын ала білетін болсам, мынаны істей алар едім :
public static String apacheCommonLeftPad(String value) {
return StringUtils.leftPad(value.trim(), value.length(), "0");
}
Көріп отырғаныңыздай, code әлдеқайда аз және барлығы растаған кітапхана да пайдаланылады. Осы мақсатта мен LeftPadExampleTest сыныбында екі тест жасадым (әдетте олар сыныпты сынауды жоспарлағанда, олар бірдей атпен класс жасайды + Бір пакетте Test, тек src/test/java ішінде). Бұл сынақтар мәнді дұрыс түрлендіретініне көз жеткізу үшін бір әдісті, содан кейін екіншісін тексереді. Әрине, көп сынақтар жазылуы керек, бірақ тестілеу біздің жағдайда негізгі тақырып емес:
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);
}
}
Мен қазір сынақтар туралы бірнеше түсініктеме бере аламын. Олар JUnit 5 көмегімен жазылған:
- Сынақ тиісті annotationға ие болса, сынақ сынақ ретінде қарастырылады - @Test.
- Егер атау сынақ жұмысын сипаттау қиын болса немесе сипаттама ұзақ және оқуға ыңғайсыз болса, @DisplayName annotationсын қосып, оны сынақтарды орындау кезінде көрінетін қалыпты сипаттамаға айналдыруға болады.
- Тесттерді жазу кезінде мен BDD әдісін қолданамын, онда мен тесттерді логикалық бөліктерге бөлемін:
- //берілген – тест алдында деректерді орнату блогы;
- //біз сынап жатқан code бөлігі іске қосылатын блок қашан;
- //онда қашан блогының нәтижелері тексерілетін блок.
- stripStart әдісі
Мұнда мен басында бос орындар мен үтірлер болуы мүмкін сызықпен мәселені шешу керек болды. Трансформациядан кейін олар жаңа мағынаға ие болмауы керек еді. Мәселе туралы мәлімдеме бұрынғыдан да анық. Бірнеше мысалдар біздің түсінігімізді нығайтады: “, , кітаптар” -> “кітаптар” “,,, кітаптар” -> “кітаптар” b , кітаптар” -> “b , кітаптар” leftPad-тегідей, мен қостым StrimStartExample класы , оның екі әдісі бар. Біреуі - өз шешімімен:
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);
}
Мұнда бос орындар немесе үтірлер жоқ индексті табу идеясы болды. Егер олар басында мүлде болмаса, онда индекс нөлге тең болады. Ал екіншісі - StringUtils арқылы шешіммен :
public static String apacheCommonLeftPad(String value) {
return StringUtils.stripStart(value, StringUtils.SPACE + COMMA);
}
Мұнда біз қай жолмен жұмыс істеп жатқанымыз туралы бірінші аргумент ақпаратын береміз, ал екіншісінде өткізіп жіберуді қажет ететін таңбалардан тұратын жолды береміз. Біз StripStartExampleTest сыныбын дәл осылай жасаймыз :
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 әдісі
Бұл әдіс, әрине, әлдеқайда қарапайым, бірақ бұл оның пайдалылығын азайтпайды. Ол String.isEmpty() әдісінің мүмкіндіктерін кеңейтеді , ол сонымен қатар нөлге тексеру қосады. Не үшін? NullPointerException болдырмау үшін, яғни null болатын айнымалыға әдістерді шақырмау . Сондықтан жазбау үшін:
if(value != null && value.isEmpty()) {
//doing something
}
Сіз мұны жай ғана жасай аласыз:
if(StringUtils.isEmpty(value)) {
//doing something
}
Бұл әдістің артықшылығы – қай әдістің қай жерде қолданылатыны бірден белгілі болады.
2. StringUtils класының басқа әдістерін талдау
Енді, менің ойымша, назар аударуға лайық әдістер туралы сөйлесейік. Жалпы StringUtils туралы айтатын болсақ, ол String класында табылғандарға ұқсас нөлдік қауіпсіз әдістерді қамтамасыз ететінін айту керек ( isEmpty әдісі сияқты ). Оларды қарастырайық:
- салыстыру әдісі
Мұндай әдіс String ішінде бар және егер екі жолды салыстыру кезінде олардың біреуі нөл болса, NullPointerException шығарады. Біздің codeта жағымсыз тексерулерді болдырмау үшін StringUtils.compare(String str1, String str2) әдісін пайдалана аламыз : ол салыстыру нәтижесі ретінде int мәнін қайтарады. Бұл құндылықтар нені білдіреді? int = 0, егер олар бірдей болса (немесе екеуі де нөл). int < 0, егер str1 str2-ден кіші болса. int > 0, егер str1 str2-ден үлкен болса. Сондай-ақ, олардың құжаттамасын қарасаңыз, осы әдістің Javadoc бағдарламасы келесі сценарийлерді ұсынады:
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
- ... әдістерін қамтиды
Мұнда утorталарды әзірлеушілер жарылыс болды. Сіз қалаған әдістің бәрі бар. Мен оларды біріктіруді шештім:
-
құрамында — күтілетін жолдың басқа жолдың ішінде екенін тексеретін әдіс. Бұл қаншалықты пайдалы? Мәтінде белгілі бір сөздің бар екеніне көз жеткізу қажет болса, бұл әдісті қолдануға болады.
Мысалдар:
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
Тағы да NPE (Null Pointer Exception) қауіпсіздігі бар.
containAny - жолда бар таңбалардың кез келгенінің бар-жоғын тексеретін әдіс. Сондай-ақ пайдалы нәрсе: мұны жиі жасауға тура келеді. Құжаттамадан мысалдар:
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 әдісінің пайдалы кеңейтімі . Шынында да, мұндай істі осы әдіссіз тексеру үшін сізге бірнеше нұсқадан өту керек. Сондықтан бір ғана әдіс үйлесімді түрде қолданылады.
-
containNone - атына қарап, не тексеріліп жатқанын түсінуге болады. Ішінде сызықтар болмауы керек. Пайдалы нәрсе, сөзсіз. Кейбір қажетсіз таңбаларды жылдам іздеу;). Telegram-ботымызда біз ұятсыздықты сүзгіден өткіземіз және бұл күлкілі әдістерді елемейміз.
Ал мысалдар, оларсыз біз қайда болар едік:
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
Құжаттардан бірнеше мысалдар:
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 әдісі
Жол бос болса және кейбір әдепкі мәнді орнату қажет болса, қосымша ақпаратты қосуды болдырмауға көмектесетін әдістер қатары. Кез келген талғамға сай көптеген нұсқалар бар. Олардың ішіндегі ең бастысы - StringUtils.defaultString (соңғы жол str, соңғы жол defaultStr) - str нөл болған жағдайда, біз мәнді defaultStr мәніне жібереміз . Құжаттамадан мысалдар:
StringUtils.defaultString(null, "NULL") = "NULL"
StringUtils.defaultString("", "NULL") = ""
StringUtils.defaultString("bat", "NULL") = "bat"
Оны деректермен POJO класын жасағанда пайдалану өте ыңғайлы.
- deleteWhitespace әдісі
Бұл қызықты әдіс, бірақ оны қолданудың көптеген нұсқалары жоқ. Сонымен қатар, егер мұндай жағдай туындаса, әдіс өте пайдалы болары сөзсіз. Ол жолдағы барлық бос орындарды жояды. Бұл олқылық қай жерде болса да, оның ізі де қалмайды))) Құжаттардан мысалдар:
StringUtils.deleteWhitespace(null) = null
StringUtils.deleteWhitespace("") = ""
StringUtils.deleteWhitespace("abc") = "abc"
StringUtils.deleteWhitespace(" ab c ") = "abc"
- endsWith әдісі
Өзі үшін сөйлейді. Бұл өте пайдалы әдіс: ол жолдың ұсынылған жолмен аяқталатынын немесе аяқталмағанын тексереді. Бұл жиі қажет. Әрине, сіз чекті өзіңіз жаза аласыз, бірақ дайын әдісті пайдалану әлдеқайда ыңғайлы және жақсырақ. Мысалдар:
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
Көріп отырғаныңыздай, бәрі бос жолмен аяқталады))) Менің ойымша, бұл мысал (StringUtils.endsWith("ABCDEF", "") = шын) тек бонус деп ойлаймын, өйткені бұл абсурд) Сондай-ақ әдіс бар. жағдайды елемейді.
- тең әдіс
Екі жолды салыстыратын нөлдік қауіпсіз әдістің тамаша мысалы. Ол жерге нені салсақ та, жауап сонда болады және ол қатесіз болады. Мысалдар:
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
Әрине, equalsIgnoreCase де бар - бәрі дәл осылай жасалады, тек біз істі елемейміз. Қарайық?
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
- тең кез келген әдіс
Келіңіздер, теңдік әдісін кеңейтейік . Бірнеше теңдікті тексерудің орнына біз біреуін орындағымыз келеді делік. Ол үшін жолдар жиынтығы салыстырылатын жолды беруге болады; егер олардың кез келгені ұсынылғанға тең болса, ол ШЫН болады. Біз оларды бір-бірімен салыстыру үшін жолды және жолдар жинағын өткіземіз (жинақтан алынған жолдармен бірінші жол). Қиын ба? Мұнда нені білдіретінін түсінуге көмектесетін құжаттардан мысалдар берілген:
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
Сондай-ақ equalsAnyIgnoreCase бар . Және оған мысалдар:
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
Төменгі сызық
Нәтижесінде біз StringUtils дегеннің не екенін және оның қандай пайдалы әдістері бар екенін білу арқылы қалдырамыз. Ал, мұндай пайдалы нәрселер бар екенін және дайын шешімнің көмегімен мәселені жабуға болатын жерлерде әр жолы балдақпен қоршаудың қажеті жоқ екенін түсіну арқылы. Жалпы, біз әдістердің бір бөлігін ғана талдадық. Қаласаңыз, мен жалғастыра аламын: олар көп және олар шынымен назар аударуға лайық. Егер сізде мұны қалай ұсынуға болатыны туралы идеяларыңыз болса, жазыңыз - мен әрқашан жаңа идеяларға ашықпын. Әдістерге арналған құжаттама өте жақсы жазылған, нәтижелермен сынақ мысалдары қосылған, бұл әдіс жұмысын жақсы түсінуге көмектеседі. Сондықтан біз құжаттаманы оқудан тартынбаймыз: бұл қызметтік бағдарламаның функционалдығына қатысты күмәніңізді жояды. Жаңа codeтау тәжірибесін алу үшін мен сізге утorта кластарының қалай жасалатынын және жазылатынын қарауға кеңес беремін. Бұл болашақта пайдалы болады, өйткені әдетте әр жобаның өз сынықтары бар және оларды жазу тәжірибесі пайдалы болады. Дәстүр бойынша, мен сізге Github-тағы аккаунтыма жазылуды ұсынамын ) Менің телеграмма боты бар жобам туралы білмейтіндер үшін мына жерде бірінші мақалаға сілтеме . Оқығаныңыз үшін барлығына рахмет. Мен төменде бірнеше пайдалы сілтемелерді қостым.пайдалы сілтемелер |
---|
GO TO FULL VERSION