Java ArrayList copy

前端 未结 8 631
说谎
说谎 2020-11-22 15:19

I have an ArrayList l1 of size 10. I assign l1 to new list reference type l2. Will l1 and l2 po

相关标签:
8条回答
  • 2020-11-22 15:37

    Yes l1 and l2 will point to the same reference, same object.

    If you want to create a new ArrayList based on the other ArrayList you do this:

    List<String> l1 = new ArrayList<String>();
    l1.add("Hello");
    l1.add("World");
    List<String> l2 = new ArrayList<String>(l1); //A new arrayList.
    l2.add("Everybody");
    

    The result will be l1 will still have 2 elements and l2 will have 3 elements.

    0 讨论(0)
  • 2020-11-22 15:51

    List.copyOf ➙ unmodifiable list

    You asked:

    Is there no other way to assign a copy of a list

    Java 9 brought the List.of methods for using literals to create an unmodifiable List of unknown concrete class.

    LocalDate today = LocalDate.now( ZoneId.of( "Africa/Tunis" ) ) ;
    List< LocalDate > dates = List.of( 
        today.minusDays( 1 ) ,  // Yesterday
        today ,                 // Today
        today.plusDays( 1 )     // Tomorrow
    );
    

    Along with that we also got List.copyOf. This method too returns an unmodifiable List of unknown concrete class.

    List< String > colors = new ArrayList<>( 4 ) ;          // Creates a modifiable `List`. 
    colors.add ( "AliceBlue" ) ;
    colors.add ( "PapayaWhip" ) ;
    colors.add ( "Chartreuse" ) ;
    colors.add ( "DarkSlateGray" ) ;
    List< String > masterColors = List.copyOf( colors ) ;   // Creates an unmodifiable `List`.
    

    By “unmodifiable” we mean the number of elements in the list, and the object referent held in each slot as an element, is fixed. You cannot add, drop, or replace elements. But the object referent held in each element may or may not be mutable.

    colors.remove( 2 ) ;          // SUCCEEDS. 
    masterColors.remove( 2 ) ;    // FAIL - ERROR.
    

    See this code run live at IdeOne.com.

    dates.toString(): [2020-02-02, 2020-02-03, 2020-02-04]

    colors.toString(): [AliceBlue, PapayaWhip, DarkSlateGray]

    masterColors.toString(): [AliceBlue, PapayaWhip, Chartreuse, DarkSlateGray]

    You asked about object references. As others said, if you create one list and assign it to two reference variables (pointers), you still have only one list. Both point to the same list. If you use either pointer to modify the list, both pointers will later see the changes, as there is only one list in memory.

    So you need to make a copy of the list. If you want that copy to be unmodifiable, use the List.copyOf method as discussed in this Answer. In this approach, you end up with two separate lists, each with elements that hold a reference to the same content objects. For example, in our example above using String objects to represent colors, the color objects are floating around in memory somewhere. The two lists hold pointers to the same color objects. Here is a diagram.

    The first list colors is modifiable. This means that some elements could be removed as seen in code above, where we removed the original 3rd element Chartreuse (index of 2 = ordinal 3). And elements can be added. And the elements can be changed to point to some other String such as OliveDrab or CornflowerBlue.

    In contrast, the four elements of masterColors are fixed. No removing, no adding, and no substituting another color. That List implementation is unmodifiable.

    0 讨论(0)
  • 2020-11-22 15:54

    Yes, assignment will just copy the value of l1 (which is a reference) to l2. They will both refer to the same object.

    Creating a shallow copy is pretty easy though:

    List<Integer> newList = new ArrayList<>(oldList);
    

    (Just as one example.)

    0 讨论(0)
  • 2020-11-22 15:55

    There is a method addAll() which will serve the purpose of copying One ArrayList to another.

    For example you have two Array Lists: sourceList and targetList, use below code.

    targetList.addAll(sourceList);

    0 讨论(0)
  • 2020-11-22 15:57

    Java doesn't pass objects, it passes references (pointers) to objects. So yes, l2 and l1 are two pointers to the same object.

    You have to make an explicit copy if you need two different list with the same contents.

    0 讨论(0)
  • 2020-11-22 15:58

    Just for completion: All the answers above are going for a shallow copy - keeping the reference of the original objects. I you want a deep copy, your (reference-) class in the list have to implement a clone / copy method, which provides a deep copy of a single object. Then you can use:

    newList.addAll(oldList.stream().map(s->s.clone()).collect(Collectors.toList()));
    
    0 讨论(0)
提交回复
热议问题