Say I have two string arrays:
String[] first = new String[]{"12","23","44","67"};
String[] second= new String[]{"12","22","46","67"};
I searched for a function like PHP's array_diff which will give me the difference of these two arrays like this:
{"23","44"}
Is there a in-built function for this operation, or should I create a for loop and check for the differences ?
You can create two Sets from these arrays, like:
List<String> firstList = Arrays.asList(first);
List<String> secondList = Arrays.asList(second);
Set<String> firstSet = new HashSet<String>(first);
Set<String> secondSet = new HashSet<String>(second);
and then use the removeAll method:
firstSet.removeAll(secondList);
secondSet.removeAll(firstList);
so now firstList contains all the elements that are only available in the first array and secondList only the elements available in the second array.
A set that will contain only the elements available in one of the sets (without elements available in both sets) can be created using:
new HashSet<String>(firstSet).addAll(secondSet);
Guava's Sets class has a difference method.
so
Set<String> diff = Sets.difference(newHashSet(first), newHashSet(second));
PHP arrays are not arrays at all, that's why there is such weird method for diff.
If you want difference between two sets (A - B) in mathematical sense, then
1) use sets
Set<Integer> set1 = new HashSet<Integer>();
Set<Integer> set2 = new HashSet<Integer>();
2) use difference method (contains all elements in set1 that not in set2)
set1.removeAll(set2)
Note, this is assymetric difference.
Related
What I would like to achieve is to have a nested list (or array) with elements as lists (or arrays) consisting a pair of integers. This is to store some data and I would like to access those integers efficiently.
So I created a nested list in Java like this:
List combined = new ArrayList();
int x[] = new int[2];
List segl = Arrays.asList(x)
combined.addAll(segl);
the nested list will later be appended with more list like segl.
Now I want to return a element from combined. But with combined.get(0) the returned element data type is object instead of a list like segl, so I couldn't do anything with it (eg. return the single int element from segl. I have no idea how to change it to a list or array.
Based on the information you provided in the comments, you want to have 'List of Lists' where the second List has two elements. Unfortunately you can't use arrays as the generic type of a List. So what I think that you want to do is probably this:
// This is a List which holds other Lists.
List<List<Integer>> combined = new ArrayList<>();
List<Integer seql = new ArrayList<>(2); // Initialize with a size of 2.
// add justs adds seql to combined. addAll will add all elements of seql to combines
combined.add(segl);
This makes it so that combined.get(0) returns a List<Integer>.
If you are using an array you have two options:
// Using Arrays.asList(..)
List<List<Integer>> combined = new ArrayList<>();
Integer[] seql = new Integer[2];
combined.add(Arrays.asList(segl));
//If Integer[] is not possible.
List<List<Integer>> combined = new ArrayList<>();
int[] seql = new int[2];
List<Integer> seqlAsList = Arrays.stream(seql).boxed().collect(Collectors.toList());
combined.add(seqlAsList );
Is there a way to convert a List<Set<String>> mainList to a plain List, without iterating over elements?
For example this one has value:
mainList = {ArrayList#705} size = 2
0 = {HashSet#708} size = 3
0 = "A2"
1 = "A1"
2 = "A3"
1 = {HashSet#709} size = 3
0 = "A6"
1 = "A5"
2 = "A7"
I would like to have a new list like so:
list = A2,A1,A3, A6, A5, A7
If you are only curious about not using iterator, you can use simple for each loop to solve the purpose
List<Set<String>> hs = null ; // Actual given List<Set<String>
ArrayList<String> arrayList = new ArrayList<String>(); // Plain List that will contain all the strings
for(Set<String> set :hs) {
arrayList.addAll(new ArrayList<String>(set)); // adding all the elements in list from hashset
}
and with using streams(java 1.8 and above) in this way
List<Set<String>> list = null ;
List<String> al = hs.stream().flatMap(Set::stream).collect(Collectors.toList());
but can you please explain why you don't want to use iterators?
You can't. Ordinarily, the only way to copy n things is to iterate over each of them.
The only way to avoid iterating over elements would be a lower-level operation like an array copy.
An ArrayList would do this (others like LinkedList would not) but no Set implementation in the JDK provides its own toArray implementation. They all use AbstractCollection.toArray which internally iterates over all of the elements.
If you implemented or found an array-based Set implementation (which would almost certainly not be an optimal Set, however) then you could flatten an ArrayList<ArraySet<String>> by using a series of array copies without iterating over the elements.
If you are using java 1.8 and above, then you can use streams but it will still use an internal iterator. Here is an example:
List<String> list = mainList.stream() // create stream
.flatMap(Set::stream) // convert Set<String> to Stream
.collect(Collectors.toList()); // collect to new ArrayList
One of the questions I have been given asks:
All the lines should be stored in an object of
type List<Set<Integer>>.
How do you write this in Java, as in how do you initialise this list? I've never seen this before.
Please provide a link to an explanation as i'm not sure what this is called in Java so have no idea about how to learn about it. Thank You.
Its a List of Sets where each Set can hold only Integers.
Set<Integer> singlesSet = new HashSet<>();
singlesSet.add(1);
singlesSet.add(2);
Set<Integer> tensSet = new HashSet<>();
tensSet.add(10);
tensSet.add(20);
List<Set<Integer>> list = new ArrayList<>();
list.add(singlesSet);
list.add(tensSet);
System.out.println(list);
Example of usages of Set and List. Note that elements in a TreeSet are always sorted.
List<Set<Integer>> listofsets = new ArrayList<Set<Integer>>();
Set<Integer> set1 = new TreeSet<Integer>();
set1.add(1);
set1.add(2);
Set<Integer> set2 = new TreeSet<Integer>();
set2.add(6);
set2.add(4);
listofsets.add(set);
// listofsets = {{1,2}, {4,6}}
Like this List<Set<Integer>> yourList = new ArrayList<Set<Integer>>();?
You may want to take a look at https://docs.oracle.com/javase/7/docs/api/java/util/List.html
The short way:
List<Set<Integer>> list = new ArrayList<Set<Integer>>();
Set<Integer> set = new HashSet<Integer>();
list.add(set);
set.add(1);
set.add(2);
....
What is the difference between Set and List?
In Java, the List interface represents an abstract list of things. Any class the implements List (for example, LinkedList) must implement its methods and behave according to its contract.
You can essentially think of it as an array, but keep in mind that arrays are only one kind of list, and that implementations of List do no have to use arrays internally.
The Set also represents a collection of elements, but with no relationship or connection between them. Visually, you can think of a set as a sort of bag of things. You can add and remove things from the bag, but none of the items need to be related.
An Integer, of course, is just an object wrapper around Java's int primitive.
As such, a List<Set<Integer>> object would be similar to a two-dimensional array, only without a defined order in the second dimension.
You would initialize a List<Set<Integer>> as follows:
List<Set<Integer>> myList = new ArrayList<HashSet<Integer>>();
Where ArrayList and HashSet can be any classes that implement List and Set, respectively.
What's the most efficient way to create an and and ormethods over two ArrayLists?
//not coded in java
HashSet<String> first = {"hello", "to", "you"}
HashSet<String> second = {"hello", "to", "me"}
HashSet<String> and = and(first, second) = {"hello", "to"}
HashSet<String> or = or(first, second) = {"hello", "to", "you", "me"}
I need to implement those two methods (pretty easy) but I would need to do it efficiently, because I will and and or over collections with hundreds of Strings. Any tip?
To avoid confusion I'll call the methods intersection and union as the meanings of AND and OR are a little ambiguous.
There is a retainAll method on Set that will do the job of the intersection. You need to take heed of my caveats in another answer (of mine) on SO.
There is an addAll method on Collection that will do the job of union.
Here is an example:
public static void main(String[] args) throws Exception {
final Set<String> first = new HashSet<>(Arrays.asList("hello", "to", "you"));
final Set<String> second = new HashSet<>(Arrays.asList("hello", "to", "me"));
System.out.println(intersection(first, second));
System.out.println(union(first, second));
}
public static Set<String> intersection(final Set<String> first, final Set<String> second) {
final Set<String> copy = new HashSet<>(first);
copy.retainAll(second);
return copy;
}
public static Set<String> union(final Set<String> first, final Set<String> second) {
final Set<String> copy = new HashSet<>(first);
copy.addAll(second);
return copy;
}
Note use usage of Set rather than List. This serves two purposes:
Set has O(1) contains as opposed to O(n) for a List. This helps in the intersection case.
Set guarantees uniqueness. This helps in the union case.
Also note that I copy the collections before carrying out the operations - as Java passes references by value not copying would cause the original collection to be changed.
If you need to preserve order, you will need to use a LinkedHashSet as a HashSet has no order.
You can use Set for that, just need to cast.
List<String> list = new ArrayList<String>();
Set<String> set = new HashSet<String>(list);
And use its methods to do that
You want to make the intersection and the union of two ArrayLists.
I think that this is a duplicate question.
I suggest to take a look at this thread:
Intersection and union of ArrayLists in Java
I have a small code that includes citynames which will be displayed.
Now a want a user can add names with a scanner, I know the code for the scanner but not how to add the variable.
Code I have:
String[] cityNames = { "Tiel", "Culemborg", "Houten", "Geldermalsen", "Meteren", "Buren" };
System.out.println(Arrays.toString(cityNames));
No you cannot do it with a Array since the size is fixed , once it declared.
You are probably looking for Collections. Prefer to Use List interface with ArrayList implementation.
The reason is that the ArrayList is
Resizable-array implementation of the List interface.
List<String> cityNames = new ArrayList<>();
Now you have methods like add, remove, ... and many more useful methods on your cityNames List
You can use a List<String>, get the input value and add it:
List<String> cities = new ArrayList<>();
cities.add(userInput);
List is better to use than array as its length is modifiable.
Arrays have a fixed length. If the amount of Strings in your collection is variable, you´ll have to use a List.
You can add new element to array if index of new element less than the size of array.
arr[i]="some value" // to do this i < arr.length
If array is completely filled with elements when you assign new value to index previous value will override. You can't add more elements than the size of declared since array has fixed size.
Array is fixed size so you can't add the value to it if the size is already filled. For dynamic array use List instead of array.
Do like this
List<String> list = new ArrayList<String>(Arrays.asList("Tiel", "Culemborg", "Houten", "Geldermalsen", "Meteren", "Buren" ));
list.add("new value1");
list.add("new value2");
It's better to use there set, which excludes duplicate entries automatically:
Set<String> cities = new HashSet<String>();
cities.addAll(Arrays.asList("Tiel", "Culemborg", "Houten", "Geldermalsen", "Meteren", "Buren"));
then to add new city just call:
sities.add(newCity);
Scanner input = new Scanner(System.in);
List<String> cityNames = new ArrayList<String>();
//Add the city names to cityNames list...
cityNames.add(input.next());