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?
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);
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
#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
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));
Related
I want to merge two corresponding values of two different variables with comma separator in a row :
like
Plate Numbers(Output) : MH 35353, AP 35989, NA 24455, DL 95405.
There is two different variables one is plate State and another is plate Number, I want to merge them together with their corresponding values like 1st values of plate State with 1st value of plate Number after that comma then so on..
I tried this code snippet but didn't work :
ArrayList<String>
list1 = new ArrayList<String>();
list1.add("MH");
list1.add("AP");
list1.add("NA ");
list1.add("DL");
ArrayList<String>
list2 = new ArrayList<String>();
list2.add("35353");
list2.add("35989");
list2.add("24455");
list2.add("95405");
list1.addAll(list2);
use this :
ArrayList<String>
list1 = new ArrayList<String>();
list1.add("MH");
list1.add("AP");
list1.add("NA ");
list1.add("DL");
ArrayList<String>
list2 = new ArrayList<String>();
list2.add("35353");
list2.add("35989");
list2.add("24455");
list2.add("95405");
Iterator iterable = list2.iterator();
List<String> list3 =list1.stream()
.map(x->{
x= x+" "+((String) iterable.next());
return x;})
.collect(Collectors.toList());
String output = String.join(", ", list3);
System.out.println(output);
From ArrayList#addAll Javadoc:
Appends all of the elements in the specified collection to the end of this list[...]
This is not what you want, because you actually don't want to append the objects, you want to merge the String of the first list with the String from the second list. So in a sense, not merge the List but merge the objects (Strings) in the lists.
The easiest (most beginner friendly) solution would be to just create a simple helper method yourself, that does what you need.
Something like this:
public static void main(String[] args) {
ArrayList<String> list1 = new ArrayList<String>();
list1.add("MH");
list1.add("AP");
list1.add("NA");
list1.add("DL");
ArrayList<String> list2 = new ArrayList<String>();
list2.add("35353");
list2.add("35989");
list2.add("24455");
list2.add("95405");
ArrayList<String> combined = combinePlateNumbers(list1, list2);
System.out.println(combined);
}
private static ArrayList<String> combinePlateNumbers(List<String> list1, List<String> list2) {
ArrayList<String> result = new ArrayList<>();
if (list1.size() != list2.size()) {
// lists don't have equal size, not compatible
// your decision on how to handle this
return result;
}
// iterate the list and combine the strings (added optional whitespace here)
for (int i = 0; i < list1.size(); i++) {
result.add(list1.get(i).concat(" ").concat(list2.get(i)));
}
return result;
}
Output:
[MH 35353, AP 35989, NA 24455, DL 95405]
I would like to compare two arrays. I have the following
ArrayList<String> time_durations = new ArrayList<String>();
time_durations.add("1200-1304")
time_durations.add("6-7")
Then the other array has the following structure
ArratList<FetchedData> apiresult = new ArrayList<FetchedData>();
apiresult.add(new FetchedData("1200-1304", //an array of data))
The class fetched data has
class FetchedData{
private String duration_range;
private ArrayList data;
//then setters and getters
//and also a constructor
}
So i want to compare the two arrays and get all items contained in time_durations but not in apiresult
Samples of them both in a json format is
time_durations = ["1200-1304", "6-7"]
apiresult = [{duration_range:"1200-1304", data:["item1", "item 2"]}
So by comparison i expect it to return the item in array time_durations6-7 that is index 1
So i have tried
if (Arrays.equals(time_durations, apiresult)) {
//this throws an error
}
But the above attempt doesnt work and am stuck.How do i achieve this?
I have checked on This question but still fails
Your code doesn't work as you expected because the first ArrayList is an array of String and the second is an Array of FetchedData. You basically try to compare two ArrayList of different type and this return false by default.
If you want to reach the goals you must map the ArrayList of FetchedData into an ArrayList of String and with Java8 it is possible to do this with a Map function and after you are enable to comparing the two array
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import static java.util.stream.Collectors.toList;
import static org.junit.Assert.assertArrayEquals;
public class TestClass {
#Test
public void arrayListComparation(){
List<String> expected = Arrays.asList("6-7");
ArrayList<String> time_durations = new ArrayList<String>();
time_durations.add("1200-1304");
time_durations.add("6-7");
ArrayList<FetchedData> apiresult = new ArrayList<>();
List<String> data = Arrays.asList("item1","item2");
apiresult.add(new FetchedData("1200-1304", data));
List<String> apiResultDurationRanges = apiresult.stream().map(FetchedData::getDuration_range).collect(toList());
time_durations.removeAll(apiResultDurationRanges);
assertArrayEquals(time_durations.toArray(),expected.toArray());
}
}
In this example you have on time_durations all element that not appear into apiResult
Iterate over the API results, get each duration and put them into a set. Remove the elements of the set from the list.
Set<String> apiDurations = apiresult.stream()
.map(FetchedData::getDuration)
.collect(Collectors.toSet());
time_durations.removeAll(apiDurations);
You can use Collection.removeAll:
List<String> apiResult_durations = apiresult.stream()
.map(FetchedData::getDuration_range)
.collect(Collectors.toList());
time_durations.removeAll(apiResult_durations);
After this code, time_durations is only [6-7]
Important to note that this will modify time_durations inline.
If you'd rather not modify it inline, then you can make a copy:
List<String> time_durations_copy = new ArrayList<>(time_durations);
time_durations_copy.removeAll(apiResult_durations);
I think you need the operation of set difference.
import java.util.ArrayList;
public class Main {
public static void main(String[] args) {
ArrayList<String> time_durations = new ArrayList<String>();//The list with some elements
ArrayList<String> otherList = new ArrayList<String>();//Another list
ArrayList<String> difference = new ArrayList<String>();//The result
time_durations.add("1200-1304");//Add some data
time_durations.add("6-7");
otherList.add("1200-1304");
for (int i = 0; i < time_durations.size(); i++) {
if (!otherList.contains(time_durations.get(i))) {
difference.add(time_durations.get(i)); // get all items contained in time_durations but not in apiresult
}
}
for (String string : difference) {
System.out.println(string);
}
}
}
Hi I have an arraylist of arraylist in this format:
[[val1, val2],[val3,val4],[val1,val2],[val1,val5]]
and would like to get the unique set of arraylists:
[[val1, val2],[val3,val4],[val1,val5]]
I have tried the following:
Set<String> uniques = new HashSet<>();
for (ArrayList<String> sublist : mappedEntities) {
uniques.addAll(sublist);
}
but this merges all the values of the internal arraylist together
can use Java 8 Collection Stream Distinct,
return in Set datatype :
Set<List<String>> uniques = mappedEntities.stream().distinct().collect(Collectors.toSet());
if you want return in List :
List<List<String>> uniques = mappedEntities.stream().distinct().collect(Collectors.toList());
Why not simply put them in a Set like this?
Set<List<String>> uniques = new HashSet<>(mappedEntities);
Your mistake is that you are flattening the inner lists and putting their items in the set separately.
The issue here is that you need a Set of ArrayList Set<ArrayList<String>>, but you are using a Set of Strings Set<String> instead.
Given the list :
List<List<String>> mappedEntities = Arrays.asList(Arrays.asList("val1", "val2"),
Arrays.asList("val3", "val4"),
Arrays.asList("val1", "val2"),
Arrays.asList("val1", "val5"));
All you need to do is just declare the set and use the addAll().
Set<List<String>> mySet = new HashSet<>();
mySet.addAll(mappedEntities);
Since a set can hold only unique values, all duplicates will not be added to the set (No need to explicitly check this). You can now print it out :
mySet.forEach(System.out::println);
Or more simply, initialize the HashSet using the list mappedEntities :
Set<List<String>> mySet = new HashSet<>(mappedEntities);
I am beginner on STACKOVERFLOW but i to try solve your problem
I think you want like this..
import java.util.*;
public class GFG {
public static void main(String[] args)
{
int n = 3;
// Here aList is an ArrayList of ArrayLists
ArrayList<ArrayList<String> > aList =
new ArrayList<ArrayList<String> >(n);
// Create n lists one by one and append to the
// master list (ArrayList of ArrayList)
ArrayList<String> a1 = new ArrayList<String>();
a1.add("1");
a1.add("2");
aList.add(a1);
ArrayList<String> a2 = new ArrayList<String>();
a2.add("11");
a2.add("22");
aList.add(a2);
ArrayList<String> a3 = new ArrayList<String>();
a3.add("1");
a3.add("2");
aList.add(a3);
Set<ArrayList<String>> uniques = new HashSet<ArrayList<String>>();
for (ArrayList<String> sublist : aList) {
uniques.add(sublist);
}
System.out.println("Your Answer");
for (ArrayList<String> x : uniques)
System.out.println(x);
}
}
try this code:
public class B {
public static void main(String[] args) throws Exception {
List<List<String>> list= Arrays.asList(
Arrays.asList("a","b","c"),
Arrays.asList("a","b","c"),
Arrays.asList("a","b","c","d"));
Set<List<String>> uniques = new HashSet<>();
for (List<String> sublist : list) {
if(!uniques.contains(sublist))
uniques.add(sublist);
}
System.out.println(uniques);
}
}
output:
[[a, b, c], [a, b, c, d]]
I have on ArrayList which contains data like this: 13-ITEM,14-ITEM,15-ITEMGROUP (with a hyphen (-) as the separator).
I want to split this list into two new ArrayLists:
ArrayList-1 containing the ids: [13,14,15..]
ArrayList-2 containing the Strings: [ITEM,ITEM,ITEMGROUP...]
I am new to Java. Thanks in advance.
You can use String#indexOf(char) to find the index in the String of the separator then use String#substring to extract the sub strings, as next:
List<String> list = Arrays.asList("13-ITEM","14-ITEM","15-ITEMGROUP");
List<String> list1 = new ArrayList<>(list.size());
List<String> list2 = new ArrayList<>(list.size());
for (String s : list) {
int index = s.indexOf('-');
// Add what we have before the separator in list1
list1.add(s.substring(0, index));
// Add what we have after the separator in list2
list2.add(s.substring(index + 1));
}
System.out.printf("List 1 = %s, List 2 = %s%n", list1, list2);
Output:
List 1 = [13, 14, 15], List 2 = [ITEM, ITEM, ITEMGROUP]
Split each entry and add the parts to the different lists. If the texts contain more -s, then use substring.
ArrayList<String> input = ...
List<String> output1 = new ArrayList<>(input.size());
List<String> output2 = new ArrayList<>(input.size());
for(String item:input){
String[] splitted = item.split("-");
output1.add(splitted[0]);
output2.add(splitted[1]);
}
You can use the following code
List<String> list = Arrays.asList("13-ITEM", "14-ITEM", "15-ITEMGROUP");
list.stream().map(p -> p.substring(0, p.indexOf('-'))).forEach(System.out::println);
list.stream().map(p -> p.substring(p.indexOf('-') + 1)).forEach(System.out::println);
If you split your concerns like this (each list is created using different logic), you will have a possibility to encapsulate code further. For example you can add some exception handling.
private static Function<String, String> getFunction() {
return new Function<String, String>() {
#Override
public String apply(String p) {
return p.substring(0, p.indexOf('-'));
}
};
}
Basically I have two arrays each filled with the same number of values (although the number of values in each array will stay the same, the number of these values can increase or decrease etc.)
The first array list has a list of names e.g.
Sam
Dean
Alice
Jane
Steve
The second array list has a list of index locations which I would like the above items to be stored at with a 3rd list-array e.g.
2nd array index locations.
3
2
5
1
4
I have used arraylists as below:
ArrayList namelist = new ArrayList();
Simply sort the list with names. You can use Collections.sort() because the strings are compareable. Then create the new list an add the string in the order of the indices.
List<String> newList = new ArrayList<>(); // or new ArrayList<String>(); for source level below 1.7
Collections.sort(nameslist);
for(Integer idx : indexList)
{
newList.add(nameslist.get(idx - 1));
}
You have to create a third array with the same size as the other two. Then you have to use the values of intArray as indices for the sortedStrArray like so:
public class JavaApplication
{
// Utilisation
public static void main(String[] args)
{
// The arrays are just here to make the initialization shorter.
// You can initialize strArrayList and
// intArrayList from the beginning with the add method if you want.
String strArray[] = new String[] { "Sam", "Dean", "Alice", "Jane", "Steve" };
Integer intArray[] = new Integer[] { 3, 2, 5, 1, 4 };
// Put array data in ArrayLists
List<String> strArrayList = new ArrayList<String>(Arrays.asList(strArray));
List<Integer> intArrayList = new ArrayList<Integer>(Arrays.asList(intArray));
List<String> sortedList = sortArrayListByIndices(strArrayList, intArrayList);
// Output order should be: Jane, Dean, Sam, Steve, Alice
for(String str : sortedList)
{
System.out.println(str);
}
}
// Implementation
public static List<String> sortArrayListByIndices(List<String> strArrayList,
List<Integer> intArrayList)
{
String sortedStrArray[] = new String[strArrayList.size()];
int i = 0;
for(String str : strArrayList) // Iterator is better style
{
// indices start with 1, array starts with 0
final int index = intArrayList.get(i) - 1;
sortedStrArray[index] = str;
i++;
}
return new ArrayList<String>(Arrays.asList(sortedStrArray));
}
}
The desired algorithm has its own method now and I wrote a little program that utilizes/tests it.