1 /*
   2  * Copyright (c) 2016, 2017, 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 
  24 /*
  25  * @test
  26  * @bug 8079136
  27  * @library /test/lib
  28  * @build jdk.test.lib.RandomFactory
  29  * @run testng SubList
  30  * @summary Basic functionality of sublists
  31  * @key randomness
  32  */
  33 
  34 import java.util.AbstractList;
  35 import java.util.Arrays;
  36 import java.util.ArrayList;
  37 import java.util.Collections;
  38 import java.util.ConcurrentModificationException;
  39 import java.util.Iterator;
  40 import java.util.LinkedList;
  41 import java.util.List;
  42 import java.util.ListIterator;
  43 import java.util.Random;
  44 import java.util.Vector;
  45 
  46 import org.testng.annotations.Test;
  47 import org.testng.annotations.DataProvider;
  48 
  49 import jdk.test.lib.RandomFactory;
  50 
  51 
  52 public class SubList extends org.testng.Assert {
  53 
  54     final Random rnd = RandomFactory.getRandom();
  55 
  56     @Test(dataProvider = "modifiable")
  57     public void testAdd(List<Integer> list, int from, int to) {
  58         List<Integer> subList = list.subList(from, to);
  59         Integer e = rnd.nextInt();
  60         subList.add(e);
  61         assertEquals(list.get(to), e);
  62         assertEquals(subList.size(), to - from + 1);
  63     }
  64 
  65     @Test(dataProvider = "modifiable",
  66           expectedExceptions = ConcurrentModificationException.class)
  67     public void testModAdd(List<Integer> list, int from, int to) {
  68         List<Integer> subList = list.subList(from, to);
  69         list.add(42);
  70         subList.add(42);
  71     }
  72 
  73     @Test(dataProvider = "unresizable",
  74           expectedExceptions = UnsupportedOperationException.class)
  75     public void testUnmodAdd(List<Integer> list, int from, int to) {
  76         List<Integer> subList = list.subList(from, to);
  77         subList.add(42);
  78     }
  79 
  80     @Test(dataProvider = "modifiable")
  81     public void testAddAtPos(List<Integer> list, int from, int to) {
  82         List<Integer> subList = list.subList(from, to);
  83         int i = rnd.nextInt(1 + to - from);
  84         Integer e = rnd.nextInt();
  85         subList.add(i, e);
  86         assertEquals(list.get(from + i), e);
  87         assertEquals(subList.size(), to - from + 1);
  88     }
  89 
  90     @Test(dataProvider = "modifiable",
  91           expectedExceptions = ConcurrentModificationException.class)
  92     public void testModAddAtPos(List<Integer> list, int from, int to) {
  93         List<Integer> subList = list.subList(from, to);
  94         list.add(42);
  95         int i = rnd.nextInt(1 + to - from);
  96         subList.add(i, 42);
  97     }
  98 
  99     @Test(dataProvider = "unresizable",
 100           expectedExceptions = UnsupportedOperationException.class)
 101     public void testUnmodAddAtPos(List<Integer> list, int from, int to) {
 102         List<Integer> subList = list.subList(from, to);
 103         int i = rnd.nextInt(1 + to - from);
 104         subList.add(i, 42);
 105     }
 106 
 107     @Test(dataProvider = "modifiable")
 108     public void testClear(List<Integer> list, int from, int to) {
 109         List<Integer> subList = list.subList(from, to);
 110         subList.clear();
 111         assertTrue(subList.isEmpty());
 112         assertEquals(subList.size(), 0);
 113     }
 114 
 115     @Test(dataProvider = "modifiable",
 116           expectedExceptions = ConcurrentModificationException.class)
 117     public void testModClear(List<Integer> list, int from, int to) {
 118         List<Integer> subList = list.subList(from, to);
 119         list.add(42);
 120         subList.clear();
 121     }
 122 
 123     @Test(dataProvider = "unresizable",
 124           expectedExceptions = UnsupportedOperationException.class)
 125     public void testUnmodClear(List<Integer> list, int from, int to) {
 126         List<Integer> subList = list.subList(from, to);
 127         subList.clear();
 128     }
 129 
 130     @Test(dataProvider = "all")
 131     public void testEquals(List<Integer> list, int from, int to) {
 132         List<Integer> subList1 = list.subList(from, to);
 133         List<Integer> subList2 = list.subList(from, to);
 134         assertTrue(subList1.equals(subList2));
 135         assertEquals(subList1.hashCode(), subList2.hashCode());
 136         for (int i = 0; i != 16; ++i) {
 137             int from3 = rnd.nextInt(1 + list.size());
 138             int to3 = from3 + rnd.nextInt(1 + list.size() - from3);
 139             boolean equal = (to - from) == (to3 - from3);
 140             for (int j = 0; j < to - from && j < to3 - from3; ++j)
 141                 equal &= list.get(from + j) == list.get(from3 + j);
 142             List<Integer> subList3 = list.subList(from3, to3);
 143             assertEquals(subList1.equals(subList3), equal);
 144         }
 145     }
 146 
 147 //    @Test(dataProvider = "modifiable",
 148 //          expectedExceptions = ConcurrentModificationException.class)
 149 //    public void testModEquals(List<Integer> list, int from, int to) {
 150 //        List<Integer> subList = list.subList(from, to);
 151 //        list.add(42);
 152 //        subList.equals(subList);
 153 //    }
 154 
 155     @Test(dataProvider = "modifiable",
 156           expectedExceptions = ConcurrentModificationException.class)
 157     public void testModHashCode(List<Integer> list, int from, int to) {
 158         List<Integer> subList = list.subList(from, to);
 159         list.add(42);
 160         subList.hashCode();
 161     }
 162 
 163     @Test(dataProvider = "all")
 164     public void testGet(List<Integer> list, int from, int to) {
 165         List<Integer> subList = list.subList(from, to);
 166         for (int i = 0; i < to - from; ++i)
 167             assertEquals(list.get(from + i), subList.get(i));
 168     }
 169 
 170     @Test(dataProvider = "modifiable",
 171           expectedExceptions = ConcurrentModificationException.class)
 172     public void testModGet(List<Integer> list, int from, int to) {
 173         List<Integer> subList = list.subList(from, to);
 174         list.add(42);
 175         subList.get(from);
 176     }
 177 
 178     @Test(dataProvider = "all")
 179     public void testIndexOf(List<Integer> list, int from, int to) {
 180         List<Integer> subList = list.subList(from, to);
 181         if (from < to) {
 182             Integer e = list.get(from);
 183             int j = subList.indexOf(e);
 184             assertTrue(j == 0);
 185         }
 186         for (int i = 0; i < list.size(); ++i) {
 187             Integer e = list.get(i);
 188             int j = subList.indexOf(e);
 189             if (i < from || i >= to) {
 190                 assertTrue(j == -1 || subList.get(j) == e);
 191             } else {
 192                 assertTrue(j >= 0);
 193                 assertTrue(j <= i - from);
 194                 assertEquals(subList.get(j), e);
 195             }
 196         }
 197         for (int i = 0; i < 16; ++i) {
 198             Integer r = rnd.nextInt();
 199             if (list.contains(r)) continue;
 200             int j = subList.indexOf(r);
 201             assertTrue(j == -1);
 202         }
 203     }
 204 
 205     @Test(dataProvider = "modifiable",
 206           expectedExceptions = ConcurrentModificationException.class)
 207     public void testModIndexOf(List<Integer> list, int from, int to) {
 208         List<Integer> subList = list.subList(from, to);
 209         list.add(42);
 210         subList.indexOf(from);
 211     }
 212 
 213     @Test(dataProvider = "all")
 214     public void testIterator(List<Integer> list, int from, int to) {
 215         List<Integer> subList = list.subList(from, to);
 216         Iterator<Integer> it = subList.iterator();
 217         for (int i = from; i < to; ++i) {
 218             assertTrue(it.hasNext());
 219             assertEquals(list.get(i), it.next());
 220         }
 221         assertFalse(it.hasNext());
 222     }
 223 
 224     @Test(dataProvider = "modifiable",
 225           expectedExceptions = ConcurrentModificationException.class)
 226     public void testModIteratorNext(List<Integer> list, int from, int to) {
 227         List<Integer> subList = list.subList(from, to);
 228         Iterator<Integer> it = subList.iterator();
 229         list.add(42);
 230         it.next();
 231     }
 232 
 233     @Test(dataProvider = "modifiable")
 234     public void testIteratorRemove(List<Integer> list, int from, int to) {
 235         List<Integer> subList = list.subList(from, to);
 236         Iterator<Integer> it = subList.iterator();
 237         for (int i = from; i < to; ++i) {
 238             assertTrue(it.hasNext());
 239             assertEquals(list.get(from), it.next());
 240             it.remove();
 241         }
 242         assertFalse(it.hasNext());
 243         assertTrue(subList.isEmpty());
 244     }
 245 
 246     @Test(dataProvider = "modifiable",
 247           expectedExceptions = ConcurrentModificationException.class)
 248     public void testModIteratorRemove(List<Integer> list, int from, int to) {
 249         List<Integer> subList = list.subList(from, to);
 250         Iterator<Integer> it = subList.iterator();
 251         it.next();
 252         list.add(42);
 253         it.remove();
 254     }
 255 
 256     @Test(dataProvider = "unresizable",
 257           expectedExceptions = UnsupportedOperationException.class)
 258     public void testUnmodIteratorRemove(List<Integer> list, int from, int to) {
 259         List<Integer> subList = list.subList(from, to);
 260         Iterator<Integer> it = subList.iterator();
 261         it.next();
 262         it.remove();
 263     }
 264 
 265     @Test(dataProvider = "all")
 266     public void testIteratorForEachRemaining(List<Integer> list, int from, int to) {
 267         List<Integer> subList = list.subList(from, to);
 268         for (int k = 0; k < 16; ++k) {
 269             int r = from + rnd.nextInt(1 + to - from);
 270             Iterator<Integer> it = subList.iterator();
 271             for (int i = from; i < to; ++i) {
 272                 assertTrue(it.hasNext());
 273                 if (i == r) {
 274                     Iterator<Integer> jt = list.listIterator(r);
 275                     it.forEachRemaining(x ->
 276                         assertTrue(jt.hasNext() && x == jt.next()));
 277                     break;
 278                 }
 279                 assertEquals(list.get(i), it.next());
 280             }
 281             it.forEachRemaining(x -> fail());
 282         }
 283     }
 284 
 285     @Test(dataProvider = "all")
 286     public void testLastIndexOf(List<Integer> list, int from, int to) {
 287         List<Integer> subList = list.subList(from, to);
 288         if (from < to) {
 289             Integer e = list.get(to - 1);
 290             int j = subList.lastIndexOf(e);
 291             assertTrue(j == to - from - 1);
 292         }
 293         for (int i = 0; i < list.size(); ++i) {
 294             Integer e = list.get(i);
 295             int j = subList.lastIndexOf(e);
 296             if (i < from || i >= to) {
 297                 assertTrue(j == -1 || subList.get(j) == e);
 298             } else {
 299                 assertTrue(j >= 0 && j >= i - from);
 300                 assertEquals(subList.get(j), e);
 301             }
 302         }
 303         for (int i = 0; i < 16; ++i) {
 304             Integer r = rnd.nextInt();
 305             if (list.contains(r)) continue;
 306             int j = subList.lastIndexOf(r);
 307             assertTrue(j == -1);
 308         }
 309     }
 310 
 311     @Test(dataProvider = "modifiable",
 312           expectedExceptions = ConcurrentModificationException.class)
 313     public void testModLastIndexOf(List<Integer> list, int from, int to) {
 314         List<Integer> subList = list.subList(from, to);
 315         list.add(42);
 316         subList.lastIndexOf(42);
 317     }
 318 
 319     @Test(dataProvider = "unresizable")
 320     public void testListIterator(List<Integer> list, int from, int to) {
 321         List<Integer> subList = list.subList(from, to);
 322         ListIterator<Integer> it = subList.listIterator();
 323         for (int i = from; i < to; ++i) {
 324             assertTrue(it.hasNext());
 325             assertTrue(it.nextIndex() == i - from);
 326             assertEquals(list.get(i), it.next());
 327         }
 328         assertFalse(it.hasNext());
 329     }
 330 
 331     @Test(dataProvider = "modifiable",
 332           expectedExceptions = ConcurrentModificationException.class)
 333     public void testModListIteratorNext(List<Integer> list, int from, int to) {
 334         List<Integer> subList = list.subList(from, to);
 335         ListIterator<Integer> it = subList.listIterator();
 336         list.add(42);
 337         it.next();
 338     }
 339 
 340     @Test(dataProvider = "modifiable")
 341     public void testListIteratorSet(List<Integer> list, int from, int to) {
 342         List<Integer> subList = list.subList(from, to);
 343         ListIterator<Integer> it = subList.listIterator();
 344         for (int i = from; i < to; ++i) {
 345             assertTrue(it.hasNext());
 346             assertTrue(it.nextIndex() == i - from);
 347             assertEquals(list.get(i), it.next());
 348             Integer e = rnd.nextInt();
 349             it.set(e);
 350             assertEquals(list.get(i), e);
 351         }
 352         assertFalse(it.hasNext());
 353     }
 354 
 355     @Test(dataProvider = "modifiable",
 356           expectedExceptions = ConcurrentModificationException.class)
 357     public void testModListIteratorSet(List<Integer> list, int from, int to) {
 358         List<Integer> subList = list.subList(from, to);
 359         ListIterator<Integer> it = subList.listIterator();
 360         it.next();
 361         list.add(42);
 362         it.set(42);
 363     }
 364 
 365     @Test(dataProvider = "unsettable",
 366           expectedExceptions = UnsupportedOperationException.class)
 367     public void testUnmodListIteratorSet(List<Integer> list, int from, int to) {
 368         List<Integer> subList = list.subList(from, to);
 369         ListIterator<Integer> it = subList.listIterator();
 370         it.next();
 371         it.set(42);
 372     }
 373 
 374     @Test(dataProvider = "unresizable")
 375     public void testListIteratorPrevious(List<Integer> list, int from, int to) {
 376         List<Integer> subList = list.subList(from, to);
 377         ListIterator<Integer> it = subList.listIterator(subList.size());
 378         for (int i = to - 1; i >= from; --i) {
 379             assertTrue(it.hasPrevious());
 380             assertTrue(it.previousIndex() == i - from);
 381             assertEquals(list.get(i), it.previous());
 382         }
 383         assertFalse(it.hasPrevious());
 384     }
 385 
 386     @Test(dataProvider = "modifiable",
 387           expectedExceptions = ConcurrentModificationException.class)
 388     public void testModListIteratorPrevious(List<Integer> list, int from, int to) {
 389         List<Integer> subList = list.subList(from, to);
 390         ListIterator<Integer> it = subList.listIterator(to - from);
 391         list.add(42);
 392         it.previous();
 393     }
 394 
 395     @Test(dataProvider = "modifiable")
 396     public void testListIteratorSetPrevious(List<Integer> list, int from, int to) {
 397         List<Integer> subList = list.subList(from, to);
 398         ListIterator<Integer> it = subList.listIterator(subList.size());
 399         for (int i = to - 1; i >= from; --i) {
 400             assertTrue(it.hasPrevious());
 401             assertTrue(it.previousIndex() == i - from);
 402             assertEquals(list.get(i), it.previous());
 403             Integer e = rnd.nextInt();
 404             it.set(e);
 405             assertEquals(list.get(i), e);
 406         }
 407         assertFalse(it.hasPrevious());
 408     }
 409 
 410     @Test(dataProvider = "unsettable",
 411           expectedExceptions = UnsupportedOperationException.class)
 412     public void testUnmodListIteratorSetPrevious(List<Integer> list, int from, int to) {
 413         List<Integer> subList = list.subList(from, to);
 414         ListIterator<Integer> it = subList.listIterator(to - from);
 415         it.previous();
 416         it.set(42);
 417     }
 418 
 419     @Test(dataProvider = "modifiable")
 420     public void testListIteratorAdd(List<Integer> list, int from, int to) {
 421         List<Integer> subList = list.subList(from, to);
 422         for (int i = 0; i < 16; ++i) {
 423             int r = rnd.nextInt(1 + subList.size());
 424             ListIterator<Integer> it = subList.listIterator(r);
 425             Integer e = rnd.nextInt();
 426             it.add(e);
 427             assertEquals(it.previous(), e);
 428             assertEquals(list.get(from + r), e);
 429         }
 430     }
 431 
 432     @Test(dataProvider = "unresizable",
 433           expectedExceptions = UnsupportedOperationException.class)
 434     public void testUnmodListIteratorAdd(List<Integer> list, int from, int to) {
 435         List<Integer> subList = list.subList(from, to);
 436         int r = rnd.nextInt(1 + subList.size());
 437         ListIterator<Integer> it = subList.listIterator(r);
 438         it.add(42);
 439     }
 440 
 441     @Test(dataProvider = "modifiable",
 442           expectedExceptions = ConcurrentModificationException.class)
 443     public void testModListIteratorAdd(List<Integer> list, int from, int to) {
 444         List<Integer> subList = list.subList(from, to);
 445         ListIterator<Integer> it = subList.listIterator();
 446         it.next();
 447         list.add(42);
 448         it.add(42);
 449     }
 450 
 451     @Test(dataProvider = "modifiable")
 452     public void testListIteratorRemoveNext(List<Integer> list, int from, int to) {
 453         List<Integer> subList = list.subList(from, to);
 454         ListIterator<Integer> it = subList.listIterator();
 455         for (int i = from; i < to; ++i) {
 456             assertTrue(it.hasNext());
 457             assertTrue(it.nextIndex() == 0);
 458             assertEquals(list.get(from), it.next());
 459             it.remove();
 460         }
 461         assertFalse(it.hasNext());
 462         assertTrue(subList.isEmpty());
 463     }
 464 
 465     @Test(dataProvider = "unresizable",
 466           expectedExceptions = UnsupportedOperationException.class)
 467     public void testUnmodListIteratorRemoveNext(List<Integer> list, int from, int to) {
 468         List<Integer> subList = list.subList(from, to);
 469         ListIterator<Integer> it = subList.listIterator();
 470         it.next();
 471         it.remove();
 472     }
 473 
 474     @Test(dataProvider = "modifiable",
 475           expectedExceptions = ConcurrentModificationException.class)
 476     public void testModListIteratorRemove(List<Integer> list, int from, int to) {
 477         List<Integer> subList = list.subList(from, to);
 478         ListIterator<Integer> it = subList.listIterator();
 479         it.next();
 480         list.add(42);
 481         it.remove();
 482     }
 483 
 484     @Test(dataProvider = "modifiable")
 485     public void testListIteratorRemovePrevious(List<Integer> list, int from, int to) {
 486         List<Integer> subList = list.subList(from, to);
 487         ListIterator<Integer> it = subList.listIterator(subList.size());
 488         for (int i = to - 1; i >= from; --i) {
 489             assertTrue(it.hasPrevious());
 490             assertTrue(it.previousIndex() == i - from);
 491             assertEquals(list.get(i), it.previous());
 492             it.remove();
 493         }
 494         assertFalse(it.hasPrevious());
 495         assertTrue(subList.isEmpty());
 496     }
 497 
 498     @Test(dataProvider = "unresizable",
 499           expectedExceptions = UnsupportedOperationException.class)
 500     public void testUnmodListIteratorRemovePrevious(List<Integer> list, int from, int to) {
 501         List<Integer> subList = list.subList(from, to);
 502         ListIterator<Integer> it = subList.listIterator(subList.size());
 503         it.previous();
 504         it.remove();
 505     }
 506 
 507     @Test(dataProvider = "modifiable")
 508     public void testRemove(List<Integer> list, int from, int to) {
 509         List<Integer> subList = list.subList(from, to);
 510         for (int i = 0; i < 16; ++i) {
 511             if (subList.isEmpty()) break;
 512             int r = rnd.nextInt(subList.size());
 513             Integer e = list.get(from + r);
 514             assertEquals(subList.remove(r), e);
 515         }
 516     }
 517 
 518     @Test(dataProvider = "unresizable",
 519           expectedExceptions = UnsupportedOperationException.class)
 520     public void testUnmodRemove(List<Integer> list, int from, int to) {
 521         List<Integer> subList = list.subList(from, to);
 522         int r = rnd.nextInt(subList.size());
 523         subList.remove(r);
 524     }
 525 
 526     @Test(dataProvider = "modifiable",
 527           expectedExceptions = ConcurrentModificationException.class)
 528     public void testModRemove(List<Integer> list, int from, int to) {
 529         List<Integer> subList = list.subList(from, to);
 530         list.add(42);
 531         subList.remove(0);
 532     }
 533 
 534     @Test(dataProvider = "modifiable")
 535     public void testSet(List<Integer> list, int from, int to) {
 536         List<Integer> subList = list.subList(from, to);
 537         for (int i = 0; i < to - from; ++i) {
 538             Integer e0 = list.get(from + i);
 539             Integer e1 = rnd.nextInt();
 540             assertEquals(subList.set(i, e1), e0);
 541             assertEquals(list.get(from + i), e1);
 542         }
 543     }
 544 
 545     @Test(dataProvider = "modifiable",
 546           expectedExceptions = ConcurrentModificationException.class)
 547     public void testModSet(List<Integer> list, int from, int to) {
 548         List<Integer> subList = list.subList(from, to);
 549         list.add(42);
 550         subList.set(0, 42);
 551     }
 552 
 553     @Test(dataProvider = "all")
 554     public void testSubList(List<Integer> list, int from, int to) {
 555         List<Integer> subList = list.subList(from, to);
 556         for (int i = 0; i < 16 && from < to; ++i) {
 557             int from1 = rnd.nextInt(to - from);
 558             int to1 = from1 + 1 + rnd.nextInt(to - from - from1);
 559             List<Integer> subSubList = subList.subList(from1, to1);
 560             for (int j = 0; j < to1 - from1; ++j)
 561                 assertEquals(list.get(from + from1 + j), subSubList.get(j));
 562         }
 563     }
 564 
 565     /**
 566      * All kinds of lists
 567      */
 568     @DataProvider
 569     public static Object[][] all() {
 570         Object[][] l1 = modifiable();
 571         Object[][] l2 = unresizable();
 572         Object[][] res = Arrays.copyOf(l1, l1.length + l2.length);
 573         System.arraycopy(l2, 0, res, l1.length, l2.length);
 574         return res;
 575     }
 576 
 577     /**
 578      * Lists that allow any modifications: resizing and setting values
 579      */
 580     @DataProvider
 581     public static Object[][] modifiable() {
 582         final List<Integer> c1 = Arrays.asList(42);
 583         final List<Integer> c9 = Arrays.asList(40, 41, 42, 43, 44, 45, -1,
 584                 Integer.MIN_VALUE, 1000500);
 585 
 586         return new Object[][] {
 587             {new ArrayList<>(c1), 0, 1},
 588             {new LinkedList<>(c1), 0, 1},
 589             {new Vector<>(c1), 0, 1},
 590             {new ArrayList<>(c1).subList(0, 1), 0, 1},
 591             {new LinkedList<>(c1).subList(0, 1), 0, 1},
 592             {new Vector<>(c1).subList(0, 1), 0, 1},
 593             {Collections.checkedList(new ArrayList<>(c1), Integer.class), 0, 1},
 594             {Collections.checkedList(new LinkedList<>(c1), Integer.class), 0, 1},
 595             {Collections.checkedList(new Vector<>(c1), Integer.class), 0, 1},
 596             {Collections.synchronizedList(new ArrayList<>(c1)), 0, 1},
 597             {Collections.synchronizedList(new LinkedList<>(c1)), 0, 1},
 598             {Collections.synchronizedList(new Vector<>(c1)), 0, 1},
 599 
 600             {new ArrayList<>(c9), 2, 5},
 601             {new LinkedList<>(c9), 2, 5},
 602             {new Vector<>(c9), 2, 5},
 603             {new ArrayList<>(c9).subList(1, 8), 1, 4},
 604             {new LinkedList<>(c9).subList(1, 8), 1, 4},
 605             {new Vector<>(c9).subList(1, 8), 1, 4},
 606             {Collections.checkedList(new ArrayList<>(c9), Integer.class), 2, 5},
 607             {Collections.checkedList(new LinkedList<>(c9), Integer.class), 2, 5},
 608             {Collections.checkedList(new Vector<>(c9), Integer.class), 2, 5},
 609             {Collections.synchronizedList(new ArrayList<>(c9)), 2, 5},
 610             {Collections.synchronizedList(new LinkedList<>(c9)), 2, 5},
 611             {Collections.synchronizedList(new Vector<>(c9)), 2, 5},
 612         };
 613     }
 614 
 615     /**
 616      * Lists that don't allow resizing, but allow setting values
 617      */
 618     @DataProvider
 619     public static Object[][] unresizable() {
 620         final List<Integer> c1 = Arrays.asList(42);
 621         final List<Integer> c9 = Arrays.asList(40, 41, 42, 43, 44, 45, -1,
 622                 Integer.MIN_VALUE, 1000500);
 623 
 624         Object[][] l1 = unsettable();
 625         Object[][] l2 = {
 626             {c1, 0, 1},
 627             {c1.subList(0, 1), 0, 1},
 628             {Collections.checkedList(c1, Integer.class), 0, 1},
 629             {Collections.synchronizedList(c1), 0, 1},
 630             {c9, 0, 4},
 631             {c9, 4, 6},
 632             {c9.subList(1, 8), 1, 4},
 633             {c9.subList(1, 8), 0, 7},
 634             {Collections.checkedList(c9, Integer.class), 3, 6},
 635             {Collections.synchronizedList(c9), 3, 5},
 636         };
 637         Object[][] res = Arrays.copyOf(l1, l1.length + l2.length);
 638         System.arraycopy(l2, 0, res, l1.length, l2.length);
 639         return res;
 640     }
 641 
 642     /**
 643      * Lists that don't allow either resizing or setting values
 644      */
 645     @DataProvider
 646     public static Object[][] unsettable() {
 647         final List<Integer> c1 = Arrays.asList(42);
 648         final List<Integer> c9 = Arrays.asList(40, 41, 42, 43, 44, 45, -1,
 649                 Integer.MIN_VALUE, 1000500);
 650 
 651         return new Object[][] {
 652             {new MyList(1), 0, 1},
 653             {new MyList(1).subList(0, 1), 0, 1},
 654             {Collections.singletonList(42), 0, 1},
 655             {Collections.singletonList(42).subList(0, 1), 0, 1},
 656             {Collections.unmodifiableList(c1), 0, 1},
 657             {Collections.unmodifiableList(new ArrayList<>(c1)), 0, 1},
 658             {Collections.unmodifiableList(new LinkedList<>(c1)), 0, 1},
 659             {Collections.unmodifiableList(new Vector<>(c1)), 0, 1},
 660 
 661             {new MyList(9), 3, 6},
 662             {new MyList(9).subList(2, 8), 3, 6},
 663             {Collections.unmodifiableList(c9), 3, 6},
 664             {Collections.unmodifiableList(new ArrayList<>(c9)), 3, 6},
 665             {Collections.unmodifiableList(new LinkedList<>(c9)), 3, 6},
 666             {Collections.unmodifiableList(new Vector<>(c9)), 3, 6},
 667         };
 668     }
 669 
 670     static class MyList extends AbstractList<Integer> {
 671         private int size;
 672         MyList(int s) { size = s; }
 673         public Integer get(int index) { return 42; }
 674         public int size() { return size; }
 675     }
 676 }