Home | History | Annotate | Download | only in stream
      1 /*
      2  * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
      3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
      4  *
      5  * This code is free software; you can redistribute it and/or modify it
      6  * under the terms of the GNU General Public License version 2 only, as
      7  * published by the Free Software Foundation.
      8  *
      9  * This code is distributed in the hope that it will be useful, but WITHOUT
     10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
     11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
     12  * version 2 for more details (a copy is included in the LICENSE file that
     13  * accompanied this code).
     14  *
     15  * You should have received a copy of the GNU General Public License version
     16  * 2 along with this work; if not, write to the Free Software Foundation,
     17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
     18  *
     19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
     20  * or visit www.oracle.com if you need additional information or have any
     21  * questions.
     22  */
     23 package org.openjdk.tests.java.util.stream;
     24 
     25 import org.openjdk.testlib.java.util.stream.LambdaTestHelpers;
     26 
     27 import java.util.concurrent.ArrayBlockingQueue;
     28 import java.util.concurrent.ConcurrentHashMap;
     29 import java.util.concurrent.ConcurrentLinkedDeque;
     30 import java.util.concurrent.ConcurrentLinkedQueue;
     31 import java.util.concurrent.ConcurrentSkipListMap;
     32 import java.util.concurrent.ConcurrentSkipListSet;
     33 import java.util.concurrent.CopyOnWriteArrayList;
     34 import java.util.concurrent.CopyOnWriteArraySet;
     35 import java.util.concurrent.LinkedBlockingDeque;
     36 import java.util.concurrent.LinkedBlockingQueue;
     37 import java.util.concurrent.LinkedTransferQueue;
     38 import java.util.concurrent.PriorityBlockingQueue;
     39 import java.util.function.Supplier;
     40 import org.testng.annotations.DataProvider;
     41 import org.testng.annotations.Test;
     42 
     43 import java.util.*;
     44 import java.util.stream.Stream;
     45 
     46 import static org.testng.Assert.assertEquals;
     47 import static org.testng.Assert.assertTrue;
     48 
     49 /**
     50  * Tests laziness of stream operations -- mutations to the source after the stream() but prior to terminal operations
     51  * are reflected in the stream contents.
     52  */
     53 @Test
     54 public class CollectionAndMapModifyStreamTest {
     55 
     56     @DataProvider(name = "collections")
     57     public Object[][] createCollections() {
     58         List<Integer> content = LambdaTestHelpers.countTo(10);
     59 
     60         List<Collection<Integer>> collections = new ArrayList<>();
     61         collections.add(new ArrayList<>(content));
     62         collections.add(new LinkedList<>(content));
     63         collections.add(new Vector<>(content));
     64 
     65         collections.add(new HashSet<>(content));
     66         collections.add(new LinkedHashSet<>(content));
     67         collections.add(new TreeSet<>(content));
     68 
     69         Stack<Integer> stack = new Stack<>();
     70         stack.addAll(content);
     71         collections.add(stack);
     72         collections.add(new PriorityQueue<>(content));
     73         collections.add(new ArrayDeque<>(content));
     74 
     75         // Concurrent collections
     76 
     77         collections.add(new ConcurrentSkipListSet<>(content));
     78 
     79         ArrayBlockingQueue<Integer> arrayBlockingQueue = new ArrayBlockingQueue<>(content.size());
     80         for (Integer i : content)
     81             arrayBlockingQueue.add(i);
     82         collections.add(arrayBlockingQueue);
     83         collections.add(new PriorityBlockingQueue<>(content));
     84         collections.add(new LinkedBlockingQueue<>(content));
     85         collections.add(new LinkedTransferQueue<>(content));
     86         collections.add(new ConcurrentLinkedQueue<>(content));
     87         collections.add(new LinkedBlockingDeque<>(content));
     88         collections.add(new ConcurrentLinkedDeque<>(content));
     89 
     90         Object[][] params = new Object[collections.size()][];
     91         for (int i = 0; i < collections.size(); i++) {
     92             params[i] = new Object[]{collections.get(i).getClass().getName(), collections.get(i)};
     93         }
     94 
     95         return params;
     96     }
     97 
     98     @Test(dataProvider = "collections")
     99     public void testCollectionSizeRemove(String name, Collection<Integer> c) {
    100         assertTrue(c.remove(1));
    101         Stream<Integer> s = c.stream();
    102         assertTrue(c.remove(2));
    103         Object[] result = s.toArray();
    104         assertEquals(result.length, c.size());
    105     }
    106 
    107     @DataProvider(name = "maps")
    108     public Object[][] createMaps() {
    109         Map<Integer, Integer> content = new HashMap<>();
    110         for (int i = 0; i < 10; i++) {
    111             content.put(i, i);
    112         }
    113 
    114         Map<String, Supplier<Map<Integer, Integer>>> maps = new HashMap<>();
    115 
    116         maps.put(HashMap.class.getName(), () -> new HashMap<>(content));
    117         maps.put(HashMap.class.getName(), () -> new LinkedHashMap<>(content));
    118         maps.put(IdentityHashMap.class.getName(), () -> new IdentityHashMap<>(content));
    119         maps.put(WeakHashMap.class.getName(), () -> new WeakHashMap<>(content));
    120 
    121         maps.put(TreeMap.class.getName(), () -> new TreeMap<>(content));
    122         maps.put(TreeMap.class.getName() + ".descendingMap()", () -> new TreeMap<>(content).descendingMap());
    123 
    124         // The following are not lazy
    125 //        maps.put(TreeMap.class.getName() + ".descendingMap().descendingMap()", () -> new TreeMap<>(content).descendingMap().descendingMap());
    126 //        maps.put(TreeMap.class.getName() + ".headMap()", () -> new TreeMap<>(content).headMap(content.size() - 1));
    127 //        maps.put(TreeMap.class.getName() + ".descendingMap().headMap()", () -> new TreeMap<>(content).descendingMap().tailMap(content.size() - 1, false));
    128 
    129         // Concurrent collections
    130 
    131         maps.put(ConcurrentHashMap.class.getName(), () -> new ConcurrentHashMap<>(content));
    132         maps.put(ConcurrentSkipListMap.class.getName(), () -> new ConcurrentSkipListMap<>(content));
    133 
    134         Object[][] params = new Object[maps.size()][];
    135         int i = 0;
    136         for (Map.Entry<String, Supplier<Map<Integer, Integer>>> e : maps.entrySet()) {
    137             params[i++] = new Object[]{e.getKey(), e.getValue()};
    138 
    139         }
    140 
    141         return params;
    142     }
    143 
    144     @Test(dataProvider = "maps", groups = { "serialization-hostile" })
    145     public void testMapKeysSizeRemove(String name, Supplier<Map<Integer, Integer>> c) {
    146         testCollectionSizeRemove(name + " key set", c.get().keySet());
    147     }
    148 
    149     @Test(dataProvider = "maps", groups = { "serialization-hostile" })
    150     public void testMapValuesSizeRemove(String name, Supplier<Map<Integer, Integer>> c) {
    151         testCollectionSizeRemove(name + " value set", c.get().values());
    152     }
    153 
    154     @Test(dataProvider = "maps")
    155     public void testMapEntriesSizeRemove(String name, Supplier<Map<Integer, Integer>> c) {
    156         testEntrySetSizeRemove(name + " entry set", c.get().entrySet());
    157     }
    158 
    159     private void testEntrySetSizeRemove(String name, Set<Map.Entry<Integer, Integer>> c) {
    160         Map.Entry<Integer, Integer> first = c.iterator().next();
    161         assertTrue(c.remove(first));
    162         Stream<Map.Entry<Integer, Integer>> s = c.stream();
    163         Map.Entry<Integer, Integer> second = c.iterator().next();
    164         assertTrue(c.remove(second));
    165         Object[] result = s.toArray();
    166         assertEquals(result.length, c.size());
    167     }
    168 }
    169