منبع اصلی نوشتار زیر در این لینک قرار دارد

ادغام و تقسیم آرایه ها و کالکشن ها در جاوا

در این مقاله جمع و جور از وبسایت اوپن مایند، یاد خواهیم گرفت که چطور آرایه ها و کالکشن ها را در جاوا به همدیگر بچسبانیم یا از همدیگر جدا کنیم و اصطلاحاً آن ها را ادغام و یا تقسیم کنیم. برای این کار از امکانات جدید کار با stream ها در جاوا هم به خوبی استفاده می کنیم.

ادغام دو آرایه

برای شروع مثالی از ادغام دو آرایه با هم با استفاده از 

Stream.concat
را می بینیم:

public void whenJoiningTwoArrays_thenJoined() {
    String[] animals1 = new String[] { "Dog", "Cat" };
    String[] animals2 = new String[] { "Bird", "Cow" };
     
    String[] result;
    result = Stream.concat(Arrays.stream(animals1), Arrays.stream(animals2)).toArray(String[]::new);
 
    /* Let's test the result content */
    assertArrayEquals(result, new String[] { "Dog", "Cat", "Bird", "Cow" });
}

ادغام دو کالکشن

حالا دو کالکشن را با هم ادغام می کنیم

public void whenJoiningTwoCollections_thenJoined() {
        Collection<String> collection1 = Arrays.asList("Dog", "Cat");
        Collection<String> collection2 = Arrays.asList("Bird", "Cow", "Moose");

        Collection<String> result;
        result = Stream.concat(collection1.stream(), collection2.stream()).collect(Collectors.toList());

        /* Let's test the result content */
        assertTrue(result.equals(Arrays.asList("Dog", "Cat", "Bird", "Cow", "Moose")));
    }

 

ادغام دو کالکشن و اعمال Filter روی سایز عنصر

در مثال زیر ضمن ادغام دو کالکشن، به عنوان پارامتری برای فیلتر کردن اعضای موجود در کالکشن نهایی، از متد فیلتر روی طول رشته ها استفاده می کنیم. در واقع در این مثال تنها عناصری در کالکشن نهایی باقی می مانند که سایز آن ها دقیقاً برابر با سه کاراکتر باشد.

public void whenJoiningTwoCollectionsWithFilter_thenJoined() {
        Collection<String> collection1 = Arrays.asList("Dog", "Cat");
        Collection<String> collection2 = Arrays.asList("Bird", "Cow", "Moose");

        Collection<String> result;
        result = Stream.concat(collection1.stream(), collection2.stream())
                .filter(e -> e.length() == 3)
                .collect(Collectors.toList());

        /* Let's test the result content */
        assertTrue(result.equals(Arrays.asList("Dog", "Cat", "Cow")));
    }

ادغام یک آرایه در یک رشته

حالا مثالی از ادغام یک آرایه در یک رشته در جاوا را می بینیم. در این مثال ادغام با استفاده از متد

joining
از
Collectors
انجام می شود.

public void whenConvertArrayToString_thenConverted() {
        
        String[] animals = new String[] { "Dog", "Cat", "Bird", "Cow" };
        
        String result;
        result = Arrays.stream(animals).collect(Collectors.joining(", "));

        /* Let's test the result content */
        assertEquals(result, "Dog, Cat, Bird, Cow");
    }

 

ادغام یک کالکشن در یک رشته

حالا همین کار مثال بالا را اما با ادغام کالکشن در رشته، تکرار می کنیم.

public void whenConvertCollectionToString_thenConverted() {
        
        Collection<String> animals = Arrays.asList("Dog", "Cat", "Bird", "Cow");
        
        String result;
        result = animals.stream().collect(Collectors.joining(", "));


        /* Let's test the result content */
        assertEquals(result, "Dog, Cat, Bird, Cow");
    }

ادغام یک Map در یک رشته

حالا می خواهیم در جاوا از یک Map یک رشته بسازیم. هدف ما این است که رشته ای شامل تمام محتویات ساختار Map بسازیم.

فرآیند این کار بسیار به مثال های قبل شبیه است، با این تفاوت که ابتدا یک قدم اضافه داریم تا دو بخش هر عنصر Map را به هم بچسبانیم و سپس تمام تکه های به هم چسبیه را در یک رشته و با استفاده از همان متد

joining
از
Collectors
کنار همدیگر قرار می دهیم.

public void whenConvertMapToString_thenConverted() {
        
        Map<Integer, String> animals = new HashMap<>();
        animals.put(1, "Dog");
        animals.put(2, "Cat");
        animals.put(3, "Cow");

        String result;
        result = animals.entrySet().stream()
                .map(entry -> entry.getKey() + " = " + entry.getValue())
                .collect(Collectors.joining(", "));

        /* Let's test the result content */
        assertEquals(result, "1 = Dog, 2 = Cat, 3 = Cow");
    }

 

ادغام کالکشن های تو در تو با یک رشته

حالا کار را کمی پیچیده تر کنیم. می خواهیم محتویات یک کالکشن تو در تو (کالکشنی که یک یا چند عنصر آن خود کالکشن است) را در یک رشته ادغام کنیم و کنر همدیگر قرار دهیم.

در مثال زیر ما ابتدا اعضای هر کالکشن داخلی را ادغام می کنیم و سپس رشته های به دست آمده ناشی از ادغام کالکشن های داخلی را به همدیگر می چسبانیم.

public void whenConvertNestedCollectionToString_thenConverted() {
        
        Collection<List<String>> nested = new ArrayList<>();
        nested.add(Arrays.asList("Dog", "Cat"));
        nested.add(Arrays.asList("Cow", "Pig"));

        String result;
        result = nested.stream().map(nextList -> nextList.stream().collect(Collectors.joining("-")))
                .collect(Collectors.joining("; "));

        /* Let's test the result content */
        assertEquals(result, "Dog-Cat; Cow-Pig");
    }

 

چگونگی برخورد با Null Value ها در هنگام ادغام و چسباندن

با استفاده از متد filter از Collection می توانیم در حین اتصال دو کالکشن مقادیر Null را نادیده بگیریم و حذف کنیم.

در مثال زیر چگونگی این کار را مشاهده خواهید کرد.

public void whenConvertCollectionToStringAndSkipNull_thenConverted() {
        
        Collection<String> animals = Arrays.asList("Dog", "Cat", null, "Moose");
        String result;
        result = animals.stream()
                .filter(Objects::nonNull)
                .collect(Collectors.joining(", "));

        /* Let's test the result content */
        assertEquals(result, "Dog, Cat, Moose");
    }

 

تقسیم یک کالکشن به دو تا

در مثال زیر می خواهیم یک کالکشن را از وسط به دو کالکشن جاوا تقسیم کنیم.

public void whenSplitCollectionHalf_thenConverted() {
        
        Collection<String> animals = Arrays.asList("Dog", "Cat", "Cow", "Bird", "Moose", "Pig");
        
        Collection<String> result1 = new ArrayList<>();
        Collection<String> result2 = new ArrayList<>();
        
        AtomicInteger count = new AtomicInteger();
        
        int midpoint = Math.round(animals.size() / 2);

        animals.forEach(next -> {
            int index = count.getAndIncrement();
            if (index < midpoint) {
                result1.add(next);
            } else {
                result2.add(next);
            }
        });

        /* Let's test the results */
        assertTrue(result1.equals(Arrays.asList("Dog", "Cat", "Cow")));
        assertTrue(result2.equals(Arrays.asList("Bird", "Moose", "Pig")));
    }

 

تقسیم یک آرایه از رشته ها به چندتا با توجه به طول هر رشته

در واقع در این مثال ما رشته های موجود در یک آرایه را بر اساس طول آن ها گروه بندی می کنیم.

public void whenSplitArrayByWordLength_thenConverted() {
        
        String[] animals = new String[] { "Dog", "Cat", "Bird", "Cow", "Pig", "Moose"};
        
        Map<Integer, List<String>> result;
        result = Arrays.stream(animals)
                .collect(Collectors.groupingBy(String::length));

        /* Let's test the results */
        assertTrue(result.get(3).equals(Arrays.asList("Dog", "Cat", "Cow", "Pig")));
        assertTrue(result.get(4).equals(Arrays.asList("Bird")));
        assertTrue(result.get(5).equals(Arrays.asList("Moose")));
    }

 

تقسیم و جداسازی یک رشته به آرایه

بیایید مثالی از تقسیم بخش هایی از یک رشته و ریختن آن ها در آرایه را ببینیم.

public void whenConvertStringToArray_thenConverted() {
        
        String animals = "Dog, Cat, Bird, Cow";
        
        String[] result;
        result = animals.split(", ");

        /* Let's test the result */
        assertArrayEquals(result, new String[] { "Dog", "Cat", "Bird", "Cow" });
    }

 

تقسیم و جداسازی یک رشته به کالکشن

این مثال شبیه به مثال قبلی است. اما تنها یک قدم اضافه دارد و آن تبدیل آرایه به کالکشن است.

public void whenConvertStringToCollection_thenConverted() {
        
        String animals = "Dog, Cat, Bird, Cow";
        
        Collection<String> result;
        result = Arrays.asList(animals.split(", "));

        /* Let's test the result */
        assertTrue(result.equals(Arrays.asList("Dog", "Cat", "Bird", "Cow")));
    }

 

تقسیم و جداسازی یک رشته به Map

ما در این مثال رشته را دو بار تقسیم می کنیم. مرتبه اول برای به دست آوردن هر تکه که بر اساس

", "
تقسیم انجام می شود و مرتبه دوم برای به دست آوردن کلید و مقدار برای هر عنصر Map که این مرتبه تکه های تقسیم شده قبلی بر اساس
" = "
تقسیم می شوند.

public void whenConvertStringToMap_thenConverted() {

        String animals = "1 = Dog, 2 = Cat, 3 = Bird";

        Map<Integer, String> result;
        result = Arrays.stream(animals.split(", ")).map(next -> next.split(" = "))
                .collect(Collectors.toMap(entry -> Integer.parseInt(entry[0]), entry -> entry[1]));

        /* Let's test the results */
        assertEquals(result.get(1), "Dog");
        assertEquals(result.get(2), "Cat");
        assertEquals(result.get(3), "Bird");
    }

 

تقسیم یک رشته با چند جداکننده مختلف در کالکشن

به عنوان آخرین مثال، یک رشته را بر اساس چند کاراکتر جداکننده مختلف و با استفاده از عبارت منظم شامل آن ها، تقسیم می کنیم. همچنین رشته های جداشده خالی (متکشل از اسپیس) را هم در کالکشن خروجی حذف می کنیم.

public void whenConvertCollectionToStringMultipleSeparators_thenConverted() {
        
        String animals = "Dog. , Cat, Bird. Cow";

        Collection<String> result;
        result = Arrays.stream(animals.split("[,|.]"))
                .map(String::trim)
                .filter(next -> !next.isEmpty())
                .collect(Collectors.toList());

        /* Let's test the result */
        assertTrue(result.equals(Arrays.asList("Dog", "Cat", "Bird", "Cow")));
    }

 

 

در این مثال ها، ما از سادگی

String.split
و از قدرت
Stream
در جاوا ۸ استفاده کردیم تا در حالت های مختلف آرایه ها و کالکشن ها در تقسیم یا در هم ادغام و الحاق کنیم.

 



برچسب ها : ,