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