3

Consider the following code:

final Set<String> allPaths = new HashSet<String>();
for (final String path: paths) {
        allPaths.add(path);
}
final MyData d = new MyData(new ArrayList<String>(allPaths));

MyData is some class I should not touch. It should get an ArrayList as an argument. Before this day, we used that way because we didn't care about the order, that is why we used Set (so there will not be duplicated). But now, I would like to keep the order of the elements, so after some research, I found out that I can use the data structure LinkedHashSet in order to do so. So I did:

final LinkedHashSet<String> allPaths = new LinkedHashSet<String>();
for (final String path: paths) {
        allPaths .add(path);
}
final MyData d = new MyData(new ArrayList<String>(allPaths));

Problem is, I'm not sure how to convert LinkedHashSet to ArrayList. Also, I thought of using ArrayList instead of LinkedHashSet so I won't have to convert it, but I'll have to iterate over the array (O(n)).

What good, clean and effiect way should I use?

TTaJTa4
  • 810
  • 1
  • 8
  • 22
  • Possible duplicate of [Convert Set to List without creating new List](https://stackoverflow.com/questions/8892360/convert-set-to-list-without-creating-new-list) – Nicholas K Dec 30 '18 at 17:23
  • Change `MyData` to use a `Collection`. Why was it hardcoded to use an `ArrayList` in the first place? – Elliott Frisch Dec 30 '18 at 17:24
  • 1
    What is wrong with the way you are doing it? There should not be a difference in the creation of the `ArrayList` between using a `LinkedHashSet` and using any other `Set`, except that it will use the proper iteration order. – RealSkeptic Dec 30 '18 at 17:25
  • what's the problem with what you're doing right now? I mean, creating a list fro ma set is basically what you did and this is fine. what does it have to do with `O(n)`? I don't get this point. – UninformedUser Dec 30 '18 at 17:27
  • 1
    ...and I wonder what `paths` is in your code? Is that a `List` or `Set`? – Naman Dec 30 '18 at 17:30
  • ...or is `paths` even an array? – Dorian Gray Dec 30 '18 at 17:37
  • @ElliottFrisch I (partly) agree with you, but since he says "MyData is some class I should not touch.", changing the constructors signature seems to be no option. I only partly agree, because if the constructor requires **ordered** data, a general `Collection` argument doesn't express that. – Dorian Gray Dec 30 '18 at 17:40
  • @DorianGray I made it a comment, and now I'm going to ask: **why** "MyData is some class I should not touch."? A `List` (or `Iterable`) would be better then hardcoding an `ArrayList`. But since we can't **see** `MyData` I remain unconvinced as to its' inviolability. – Elliott Frisch Dec 30 '18 at 17:49
  • @ElliottFrisch I guess he uses some 3rd party library – Dorian Gray Dec 30 '18 at 17:52

4 Answers4

8

Just use the public boolean addAll(Collection<? extends E> c) method, on the arrayList, it accepts any Collection.

You have your LinkedHashSet:

final LinkedHashSet<String> allPaths = new LinkedHashSet<String>();
for (final String path: paths) {
        allPaths .add(path);
}

and then do (you can use this even if mylist is not empty):

List<String> myList = new ArrayList<>();
mylist.addAll(allPaths);

or for even a simpler approach:

List<String> myList = new ArrayList<>(allPaths);
Daniel B.
  • 2,491
  • 2
  • 12
  • 23
  • does `new ArrayList(??>)` know to handle with a collection (like `LinkedHashSet`)? If so, will my way still work? – TTaJTa4 Dec 30 '18 at 17:37
  • @TTaJTa4 yes, that is the whole point of the Collection interface. It is an abstract idea, that has many implementations, but it is basically the same thing, a **collection of things**. Java uses Collection, instead of hard coded implementations (like ArrayList for example), to be able to swap from one implementation to another - just like in your case, when you want to use LinkedHashSet instead of HashSet, without the need to re-write the method/class you are passing the argument into. – Daniel B. Dec 30 '18 at 17:41
  • `addAll` is merely an extra over what the OP already did. There is no need to use it, it can be used the way it was originally. – RealSkeptic Dec 30 '18 at 17:45
  • @RealSkeptic you call use the `addAll` method even if the list is not empty, in case he needs it, as I mentioned in my answer. – Daniel B. Dec 30 '18 at 17:46
  • I'm wondering what's different in your answer from what he already does in his question?! – UninformedUser Dec 30 '18 at 20:18
  • It is not, he merely asked if it is the way to go because he wasn’t sure of how to convert the collections , I showed him a couple of options – Daniel B. Dec 30 '18 at 20:24
2

Why dont you just convert your paths to an LinkedHashSet like that (assuming that paths is a Collection?

final MyData d = new MyData(new ArrayList<>(new LinkedHashSet<>(paths)));

In case paths is an array, you can use Arrays.asList(paths) inside the conversion above

Dorian Gray
  • 2,913
  • 1
  • 9
  • 25
0
@TTaJTa4 you can use the code below as an example. Both ways are fine.



import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.Set;

public class ConvertLinkedHashSetToArrayList
{

  public static void main(String[] args)
  {
    Set<String> testStrings = new LinkedHashSet<>();
    testStrings.add("String 1");
    testStrings.add("String 2");
    testStrings.add("String 3");
    testStrings.add("String 4");
    testStrings.add("String 5");

    System.out.println("** Printing LinkedHashSet: " + testStrings);
    ArrayList<String> linkedHashSetToArrayList1 = new ArrayList<>(testStrings);
    System.out.println("** Printing linkedHashSetToArrayList1:" + 
    linkedHashSetToArrayList1);

    ArrayList<String> linkedHashSetToArrayList2 = new ArrayList<>();
    linkedHashSetToArrayList2.addAll(testStrings);
    System.out.println("** Printing linkedHashSetToArrayList2:" + 
    linkedHashSetToArrayList2);
  }
}

Results are like:

** Printing LinkedHashSet: [String 1, String 2, String 3, String 4, String 5]
** Printing linkedHashSetToArrayList1:[String 1, String 2, String 3, String 4, String 5]
** Printing linkedHashSetToArrayList2:[String 1, String 2, String 3, String 4, String 5]

Follow the GitHub link for the full java project: GitHub example

Dilanka M
  • 372
  • 1
  • 5
  • 17
0

If paths is a collection you can get an array list no duplicates:

ArrayList<String> p = paths.stream().distinct().collect(Collectors.toCollection(ArrayList::new));

If paths is an array:

ArrayList<String> p = Stream.of(paths).distinct().collect(Collectors.toCollection(ArrayList::new));

c0der
  • 18,467
  • 6
  • 33
  • 65