Java 1.8-da, faqat bitta element bo'lsa, mantiqni foreachdan oldin bajarishi kerak

// the results can be anything, errors always start with 'ERROR'
List results= { 
    "Success 100 - Operation worked John", 
    "Success 100 - It also worked for Harry", 
    "ERROR 4514 for Sally. It's always Sally." 
}

// I want this to output something like 
//     warn: There were errors
//     warn: ERROR 4514 for Sally. It's always Sally.
//
// in the case there are no ERROR's I want no warn:'s
results.stream()
    .filter( name->name.startsWith( "ERROR" ) )
    .DO_THIS_IF_NOT_EMPTY( ()-> LOG.warn( "There were errors"; )
    .forEach( error -> { LOG.warn( "ERROR: " + error }

DO_THIS_IF_NOT_EMPTY orzu. Buni java oqimlari bilan bajarish uchun ochiq va oqilona yo'lni ko'rmayapman. Yaxshi o'ylaydigan kishi bormi?

3
qo'shib qo'ydi muallif efekctive, manba
Mening e'tirozim shuki, agar bu tejamkorlik chizig'i strategiyalarini takrorlasalar, umumiy ko'rsatkich sho'ppiradi. Shunday qilib, men biriga joylashishdan oldin ham o'lchovni yaxshi ko'raman
qo'shib qo'ydi muallif efekctive, manba
Mening e'tirozim shuki, agar bu tejamkorlik chizig'i strategiyalarini takrorlasalar, umumiy ko'rsatkich sho'ppiradi. Shunday qilib, men biriga joylashishdan oldin ham o'lchovni yaxshi ko'raman
qo'shib qo'ydi muallif efekctive, manba
@SeanPatrickFloyd Bu boshqa xulosa emas. "Stream" so'zi APIni belgilaydi. Bu kodlarning tejalishi haqida emas, balki bu ma'lumotlarning katta miqdordagi ishlovi haqida
qo'shib qo'ydi muallif efekctive, manba
@SeanPatrickFloyd Bu boshqa xulosa emas. "Stream" so'zi APIni belgilaydi. Bu kodlarning tejalishi haqida emas, balki bu ma'lumotlarning katta miqdordagi ishlovi haqida
qo'shib qo'ydi muallif efekctive, manba
qo'shib qo'ydi muallif efekctive, manba
Oqimlarning qo'shimcha xarajatlari bor. Bir necha haftadan so'ng, ushbu yuk tashuvchi, oqim o'lchamlari haqida juda yaxshi raqamlarga ega bo'lgan post bor edi. Sizning hisobingizdan kodning bir nechta kodini saqlab qolmoqdasiz
qo'shib qo'ydi muallif efekctive, manba
Oqimlarning qo'shimcha xarajatlari bor. Bir necha haftadan so'ng, ushbu yuk tashuvchi, oqim o'lchamlari haqida juda yaxshi raqamlarga ega bo'lgan post bor edi. Sizning hisobingizdan kodning bir nechta kodini saqlab qolmoqdasiz
qo'shib qo'ydi muallif efekctive, manba
Bu sizning fikringiz va men uni hurmat qilaman.
qo'shib qo'ydi muallif efekctive, manba
@fekctive ushbu post plzni topa olasizmi?
qo'shib qo'ydi muallif Eugene, manba
Oqim ichidagi barcha operatsiyalar vatansiz bo'lishi kerak. Shunday qilib, oqim bilan faqat filtrni filtrlash va chiqishni alohida-alohida qilish.
qo'shib qo'ydi muallif Timothy Truckle, manba
LOG.warn ("xatolar bor edi") , jurnal yozish tizimining butunlay noto'g'ri uchida formatlashni amalga oshirishga harakat qilayotganingizga o'xshaydi, chunki bu haqiqiy jurnali emas xabar, ammo keyingi xabarlar uchun sarlavha. Ushbu xabarlar jurnal faylida ulashganligiga kafolat yo'qligi sababli, bu mantiqiy emas. Buning o'rniga, jurnalni tahlil qilish vositasidan foydalaning, log fayllarini qaerda paydo bo'lishidan qat'iy nazar, deyarli bir vaqtning o'zida bir xil manbadan kundalik xabarlarni to'play olasiz. Keyin, bir yoki bir necha xatolik jurnalini ko'rganing aslida "xatolar bor edi" ni tan olish uchun etarli ...
qo'shib qo'ydi muallif Holger, manba
LOG.warn ("xatolar bor edi") , jurnal yozish tizimining butunlay noto'g'ri uchida formatlashni amalga oshirishga harakat qilayotganingizga o'xshaydi, chunki bu haqiqiy jurnali emas xabar, ammo keyingi xabarlar uchun sarlavha. Ushbu xabarlar jurnal faylida ulashganligiga kafolat yo'qligi sababli, bu mantiqiy emas. Buning o'rniga, jurnalni tahlil qilish vositasidan foydalaning, log fayllarini qaerda paydo bo'lishidan qat'iy nazar, deyarli bir vaqtning o'zida bir xil manbadan kundalik xabarlarni to'play olasiz. Keyin, bir yoki bir necha xatolik jurnalini ko'rganing aslida "xatolar bor edi" ni tan olish uchun etarli ...
qo'shib qo'ydi muallif Holger, manba
Odatda. Ayollar har bir narsani ayblaydi :-)
qo'shib qo'ydi muallif Sean Patrick Floyd, manba
Odatda. Ayollar har bir narsani ayblaydi :-)
qo'shib qo'ydi muallif Sean Patrick Floyd, manba
@Eugene buni biladimi, lekin men yaqinda bu javobda oqimlarga qarshi oqimlarni taqqosladim: stackoverflow.com/a/ 42627322/342852 . DR: Oqimlar o'n minglab mahsulot yoki undan ko'p narsalar bilan ishlashda samarali. Kichkina raqamlar uchun majburiy ko'chadan yaxshiroq ishlaydi
qo'shib qo'ydi muallif Sean Patrick Floyd, manba
@efekctive rost, lekin u ham kamroq xatolikka asoslangan dasturiy paradigma haqida, bu erda yon ta'sirlar tushkun
qo'shib qo'ydi muallif Sean Patrick Floyd, manba
@Eugene buni biladimi, lekin men yaqinda bu javobda oqimlarga qarshi oqimlarni taqqosladim: stackoverflow.com/a/ 42627322/342852 . DR: Oqimlar o'n minglab mahsulot yoki undan ko'p narsalar bilan ishlashda samarali. Kichkina raqamlar uchun majburiy ko'chadan yaxshiroq ishlaydi
qo'shib qo'ydi muallif Sean Patrick Floyd, manba
@efekctive rost, lekin u ham kamroq xatolikka asoslangan dasturiy paradigma haqida, bu erda yon ta'sirlar tushkun
qo'shib qo'ydi muallif Sean Patrick Floyd, manba
OPEK O'S faoliyati haqida so'ramadi. Muayyan ishlash talablari bo'lmaganida (vaqtning 99% yoki ko'prog'i, aniq kod etarli darajada tezdir), faqat aniq va yangilanuvchi kod yozishga qaratilishi kerak va agar ishlash talablari mavjud bo'lsa, faqat manzilni bajarish kerak b) u erda o'lchov metrikalari va v) o'lchovlar talablarga javob bermasligini aytadi. Bu kabi "lekin ... ishlash" bilan interyaptsiya qilish, odatda, noturg'un shovqin. Bu "chiziqni tejash" haqidagi taxminlar noto'g'ri; bu aniqlik haqida. Kodni tozalash, ehtimol to'g'ri bo'lishi mumkin.
qo'shib qo'ydi muallif Brian Goetz, manba
OPEK O'S faoliyati haqida so'ramadi. Muayyan ishlash talablari bo'lmaganida (vaqtning 99% yoki ko'prog'i, aniq kod etarli darajada tezdir), faqat aniq va yangilanuvchi kod yozishga qaratilishi kerak va agar ishlash talablari mavjud bo'lsa, faqat manzilni bajarish kerak b) u erda o'lchov metrikalari va v) o'lchovlar talablarga javob bermasligini aytadi. Bu kabi "lekin ... ishlash" bilan interyaptsiya qilish, odatda, noturg'un shovqin. Bu "chiziqni tejash" haqidagi taxminlar noto'g'ri; bu aniqlik haqida. Kodni tozalash, ehtimol to'g'ri bo'lishi mumkin.
qo'shib qo'ydi muallif Brian Goetz, manba
Bu chiziqlarni saqlab qolish emas, balki ma'no berish va kodni noto'g'ri tushunmaydigan tarzda taqdim etish.
qo'shib qo'ydi muallif user1743310, manba
@ "K" larning kundalik freymlari haqida emas, balki ko'pchilik odamlar bilan aloqador bo'lgan oddiy misolda bu haqda yozgan edim. Agar buyurtma asosida xaridorlarga buyurtma asosida yuborish uchun tuzilgan e-pochta xabarini yoki agar u sizga yordam beradigan bo'lsa, uni joylashtiradigan tarkibiy qismlar bo'lsa, siz yaratgan JFrame-ni ko'rsating. Q - java 1.8 oqimlari haqida
qo'shib qo'ydi muallif user1743310, manba
@ "K" larning kundalik freymlari haqida emas, balki ko'pchilik odamlar bilan aloqador bo'lgan oddiy misolda bu haqda yozgan edim. Agar buyurtma asosida xaridorlarga buyurtma asosida yuborish uchun tuzilgan e-pochta xabarini yoki agar u sizga yordam beradigan bo'lsa, uni joylashtiradigan tarkibiy qismlar bo'lsa, siz yaratgan JFrame-ni ko'rsating. Q - java 1.8 oqimlari haqida
qo'shib qo'ydi muallif user1743310, manba
Bu chiziqlarni saqlab qolish emas, balki ma'no berish va kodni noto'g'ri tushunmaydigan tarzda taqdim etish.
qo'shib qo'ydi muallif user1743310, manba
@efekctive qiziqarli, men ularni nuqta o'yladim, ular funktsional va siz kompilyator tarkibi tartibga solish uchun optimal strategiya tushunish uchun tark mumkin va shu sababli.
qo'shib qo'ydi muallif user1743310, manba
@efekctive qiziqarli, men ularni nuqta o'yladim, ular funktsional va siz kompilyator tarkibi tartibga solish uchun optimal strategiya tushunish uchun tark mumkin va shu sababli.
qo'shib qo'ydi muallif user1743310, manba

7 javoblar

Bunday holatda, ichki oqim operatsiyalari mavjud emas, shuning uchun Iterator dan foydalanish uchun qulab tushish eng oddiy echimdir:

Iterator it = results.stream()
    .filter(name -> name.startsWith( "ERROR" ))
    .iterator();
if(it.hasNext()) {
    LOG.warn("There were errors");
    it.forEachRemaining(error -> LOG.warn("ERROR: " + error));
}

Ya'ni, hech qanday mazmunga ega bo'lmagan "xatolar bor" kabi xabarni yozishda hech qanday ma'no yo'q, ayniqsa, keyin siz aniq xabarni taqdim etadigan mazmunli log hisobini ishlab chiqarsangiz va xatolar borligini bildirsangiz ..

Ehtimol, bu nom bo'lishi kerak, boshqacha qilib aytganda, siz jurnalni yozish tizimining to'liq noto'g'ri uchida formatlash faylini yozishga harakat qilyapsiz.

Ushbu xabarlar bir jurnali fayliga ulashganligiga kafolat bo'lmagani uchun, boshqa ish zarrachalaridan yoki kichik tizimlardan boshqa jurnali xabarlari bo'lishi mumkinligini inobatga oling, bu mantiqiy emas.

Buning o'rniga, logni tahlil qilish vositasidan foydalaning, chunki u bir xil manbadan yozuvlarni topish uchun jurnal faylini filtrlay oladi, ehtimol siz bir-biringizdan bir xil ish zarrachalaridan tez orada ochilgan narsalarni qidirib topasiz, bu sizni haqiqiy manzilidan mustaqil qiladi log faylida.

Sizga ma'lum bo'lishicha, sizda kamida bitta taalukli yozuv ko'rsatilganda "xatolar bor edi" ...

3
qo'shib qo'ydi
Keyin LOG.warn ogohlantirish xabarini yozishni aniq tarzda o'zboshimchali koddan farqli ravishda aniq bir semantikka ega bo'lgani uchun tanlangan to'ldiruvchidir. Yaxshiyamki, umumiy javobga javobni echim bilan boshladim. LOG.warn LOG.Warn so'zlarini e'tiborga olishni xohlamasligingiz kabi ikkinchi yarmini ham e'tiborsiz qoldiring ...
qo'shib qo'ydi muallif Holger, manba
Aytganidek, Iterator yordamida javobning boshida echim mavjud. siz siz aytayotgan narsalar haqida noto'g'ri gaplashib, ahamiyatga ega emas. Agar siz o'quvchilarni loggerlardan foydalanishni inobatga olmasliklarini istasangiz, nega siz yozishni saqlashga oid ko'rsatmalarni e'tiborga olmayapman? Iterator asoslangan echimdan foydalansangiz? Ha bo'lsa, yaxshi. Yo'q, yaxshi omad yaxshiroq topish. Agar o'ylab ko'rsangiz, logger qismi juda chalg'ituvchi, birinchi navbatda savolingizni yaxshilang.
qo'shib qo'ydi muallif Holger, manba
Nimaga bu munozarali munozarasi bilan vaqtimni behuda sarflayapsiz? Shunga qaramay, javob boshida bir yechim mavjud . Sizning haqiqiy kodingiz namunangizga nisbatan keyingi paragraf bor, agar siz bu tashqaridan harakat qilishingizga yordam beradigan bo'lsa, uni bo'sh qoldiring.
qo'shib qo'ydi muallif Holger, manba
Siz loggerlarni qabul qilishingiz kerak. "Java 1.8 da qanday qilib oldindan oldingi mantiqni kamida bitta element bo'lsa, oqimlarni amalga oshiradi". ramka yozishni emas, balki bir-biriga bog'liq emas. Buning orqasida harakat qilishingizga yordam beradigan bo'lsa, uni boshingizga System.out.println qiling.
qo'shib qo'ydi muallif user1743310, manba
Savol bergan narsa aniq edi. Men cho'ntagimni qanday tuzatishni so'radim, "siz qo'llaringizni yuvishga hojat yo'q" deb javob bergan edingiz. Ushbu fikrlash uslubi foydali emas. Bu semantik farqlar haqida emas va bu muammo loggerlar haqida hech narsa emas edi, bu savol java 1.8 va qanday qilib oqimlarni tuzish kerakligi aniq-men ko'pchilik odamlar bilan bog'liq bo'lgan oddiy misol sifatida loggerni taqdim qildim.
qo'shib qo'ydi muallif user1743310, manba
Bu muammo tavsifining qisqartirilganligi uchun juda soddalashtirilgan misol. Googelpost javoblarini "Xatolar bor" degan so'zlar bilan ko'chirish, ma'no jihatidan foydali bo'lgan log xabari emas, balki *** nuqta to'liq bu ekspluatatsiya qilishni kutish mumkin bo'lmagan haqiqiy muammodan pastroq bo'lgan misol. Hamma narsani o'qib chiqing. Iltimos, odamlar sizning muammosiga yaqinlashishda sizdan ko'proq aql-zakovat egasi bo'lganiga javob berishadi va men Garri, Jon va Sara uchun Strings deb yozilgan xatlarni yozish bilan shug'ullanib, uni yozishga harakat qilmayman.
qo'shib qo'ydi muallif user1743310, manba

Ro'yxatni filtrlash:

List errors = names.stream()
    .filter(name -> name.startsWith("ERROR"))
    .collect(Collectors.toList());

And if not empty, print your static line and then do forEach

if (!errors.isEmpty()) {
    LOG.warn("There were errors");
    errors.forEach(error -> LOG.warn("ERROR: " + error));
}
2
qo'shib qo'ydi
@SeanPatrickFloyd Buni ko'rsatganingiz uchun tashakkur.
qo'shib qo'ydi muallif Abubakkar, manba
Oqimlar har qanday terminal operatsiyalari oqimni baholashga olib keladigan tarzda ishlab chiqilgan. Sizning holatingizda, agar oqim bo'sh bo'lmasa, biror narsa qilishni xohlaganingizda men uchun terminalli operatsiya bo'ladi.
qo'shib qo'ydi muallif Abubakkar, manba
.size() tekshirish o'rniga, if (! errors.isEmpty ())
qo'shib qo'ydi muallif Sean Patrick Floyd, manba
Alternativ ravishda, siz kollektsiyani amalga oshirishni xohlamasangiz, iterator() terminalini ishlatishingiz mumkin, keyin keyin iteratorga o'ting.
qo'shib qo'ydi muallif Brian Goetz, manba
ishonch hosil qilsam, lekin keyin to'plashni davom ettiraman (hozirgi kod nimani anglatadi), qanday his qilsam oqimlarning ruhini yo'qotadi va sizda ko'p oqimlar okunabilirliğini yo'qotadi
qo'shib qo'ydi muallif user1743310, manba

Ro'yxatni filtrlash:

List errors = names.stream()
    .filter(name -> name.startsWith("ERROR"))
    .collect(Collectors.toList());

And if not empty, print your static line and then do forEach

if (!errors.isEmpty()) {
    LOG.warn("There were errors");
    errors.forEach(error -> LOG.warn("ERROR: " + error));
}
2
qo'shib qo'ydi
@SeanPatrickFloyd Buni ko'rsatganingiz uchun tashakkur.
qo'shib qo'ydi muallif Abubakkar, manba
Oqimlar har qanday terminal operatsiyalari oqimni baholashga olib keladigan tarzda ishlab chiqilgan. Sizning holatingizda, agar oqim bo'sh bo'lmasa, biror narsa qilishni xohlaganingizda men uchun terminalli operatsiya bo'ladi.
qo'shib qo'ydi muallif Abubakkar, manba
.size() tekshirish o'rniga, if (! errors.isEmpty ())
qo'shib qo'ydi muallif Sean Patrick Floyd, manba
Alternativ ravishda, siz kollektsiyani amalga oshirishni xohlamasangiz, iterator() terminalini ishlatishingiz mumkin, keyin keyin iteratorga o'ting.
qo'shib qo'ydi muallif Brian Goetz, manba
ishonch hosil qilsam, lekin keyin to'plashni davom ettiraman (hozirgi kod nimani anglatadi), qanday his qilsam oqimlarning ruhini yo'qotadi va sizda ko'p oqimlar okunabilirliğini yo'qotadi
qo'shib qo'ydi muallif user1743310, manba

Bu erda yana bir, ixcham, yechim:

berilgan:

List names = Arrays.asList(
        "Success 100 - Operation worked John",
        "Success 100 - It also worked for Harry",
        "ERROR 4514 for Sally. It's always Sally.");

Predicate IS_ERROR = name -> name.startsWith("ERROR");

Yilni yechim:

if (names.stream().anyMatch(IS_ERROR)) {
    LOG.warn("There were errors");
    names.stream().filter(IS_ERROR).forEach(LOG::warn);
}
2
qo'shib qo'ydi
Mening yechimim ishlash yoki resurslar uchun optimallashtirilmagan, lekin o'qilishi uchun. Bu sizning talablaringizda nima aniq ko'rsatilganligini juda aniq aks ettiradi: agar xabarlarda xato bo'lsa, ularni jurnalga yozishdan ko'ra. Siz eng yaxshi ishlashga muhtoj ekaningizni, ammo kod bazangizning okunabilirliğini va bakımlığını muhofaza qilsangiz, eng ko'p o'qilishi mumkin bo'lgan va eng kam murakkab yechim bilan borishingizni tavsiya qilaman.
qo'shib qo'ydi muallif Harmlezz, manba
qiziqarli. Ehtimol, men bularning barchasini yaxshi ko'raman. Ikkita daryo oqimdan foydalanadi, ammo bu juda aniq.
qo'shib qo'ydi muallif user1743310, manba
Darhaqiqat, men aytganidek, bu eng yaxshilar deb o'ylayman va eng ko'p ko'rgan narsalarimga o'xshaydi
qo'shib qo'ydi muallif user1743310, manba

Siz shunga o'xshash biror narsani sinashingiz mumkin

results.stream().filter(s -> s.startsWith("ERROR")).forEach(s -> System.out.println("Warning found match: "+ s));
1
qo'shib qo'ydi
To'g'ri, yomon, agar siz element elementi ERROR bilan boshlansa, siz biror narsaga kirishni xohlaysiz deb o'yladim
qo'shib qo'ydi muallif justMe, manba
Bu, aslida "xatolar bor edi" degan savolning asl nuqtasi emas
qo'shib qo'ydi muallif user1743310, manba

Bu birinchi yoki yo'qligini kuzatish uchun final AtomicBoolean ni saqlashingiz mumkin.

static String[] results = {
        "Success 100 - Operation worked John",
        "Success 100 - It also worked for Harry",
        "ERROR 4514 for Sally. It's always Sally."
};

public void test() {
    List names = Arrays.asList(results);
    final AtomicBoolean first = new AtomicBoolean(true);
    names.stream()
            .filter(name -> name.startsWith("ERROR"))
            .forEach(error -> {
                if (first.getAndSet(false)) {
                    System.out.println("There were errors ");
                }

                System.out.println("ERROR: " + error);
            });
}

IMHO @ abubakkarning yechim yaxshiroqdir.

0
qo'shib qo'ydi
@Timo siz noto'g'ri postni tahrir qildingiz deb o'ylayman. Bu javob qismidir.
qo'shib qo'ydi muallif 4castle, manba
Bu OldCurmudgeonning sharh bo'limidir, shunday emasmi? Bu OldCurmudgeonning javobiga sharh ...
qo'shib qo'ydi muallif user1743310, manba
Yaxshi, lekin bu nafis emas va u nimani tushunish uchun o'qish kerak
qo'shib qo'ydi muallif user1743310, manba

Bu birinchi yoki yo'qligini kuzatish uchun final AtomicBoolean ni saqlashingiz mumkin.

static String[] results = {
        "Success 100 - Operation worked John",
        "Success 100 - It also worked for Harry",
        "ERROR 4514 for Sally. It's always Sally."
};

public void test() {
    List names = Arrays.asList(results);
    final AtomicBoolean first = new AtomicBoolean(true);
    names.stream()
            .filter(name -> name.startsWith("ERROR"))
            .forEach(error -> {
                if (first.getAndSet(false)) {
                    System.out.println("There were errors ");
                }

                System.out.println("ERROR: " + error);
            });
}

IMHO @ abubakkarning yechim yaxshiroqdir.

0
qo'shib qo'ydi
@Timo siz noto'g'ri postni tahrir qildingiz deb o'ylayman. Bu javob qismidir.
qo'shib qo'ydi muallif 4castle, manba
Bu OldCurmudgeonning sharh bo'limidir, shunday emasmi? Bu OldCurmudgeonning javobiga sharh ...
qo'shib qo'ydi muallif user1743310, manba
Yaxshi, lekin bu nafis emas va u nimani tushunish uchun o'qish kerak
qo'shib qo'ydi muallif user1743310, manba