I have a function that gets an array of primitive data (int), I need to return the array of two elements the smallest and the largest number. If length of the array is 1 then just return two first elements int the array. I came up with such solution:
public static int[] minMax(int[] arr) {
if (arr.length==1)
return new int[]{arr[0],arr[0]} ;// return if arr is 1 element
else {
ArrayList<Integer> ar = new ArrayList<Integer>();
//?
return new int[]{Collections.max(ar),Collections.min(ar)};
}
}
But how do I convert an array to an ArrayList? Is there a more efficient way maybe?
By calling Collections.min and Collections.max, you're iterating over the array twice. You can cut this time down by streaming the array and letting it do the heavy lifting, as James Mudd suggested. However, note that by doing so you'd be wasting time on calculating the sum and accumulating the count of the elements, which you don't care about. It may be more efficient to calculated these yourself:
public static int[] minMax(int[] arr) {
// Assuming arr has at least one element
int min = arr[0];
int max = arr[0];
for (int i = 1; i < arr.length; ++i) {
int curr = arr[i];
if (curr < min) {
min = curr;
} else if (curr > max) {
max = curr;
}
}
return new int[]{min, max};
}
You could use IntSummaryStatistics the method would look like
public static int[] minMax(int[] arr) {
IntSummaryStatistics intSummaryStatistics = Arrays.stream(arr).summaryStatistics();
return new int[] {intSummaryStatistics.getMin(), intSummaryStatistics.getMax()};
}
Here's another way of solving this task with streams.
Instead, using IntSummuryStatistics we can provide an array of two elements as a container of the resulting values while applying collect and manually define to accumulate stream elements in it.
public static int[] minMax(int[] sourceArr) {
if (sourceArr.length == 0) throw new IllegalArgumentException(); // source array is empty
return Arrays.stream(sourceArr)
.collect(
() -> new int[]{sourceArr[0], sourceArr[0]}, // mutable container
(arr, next) -> { // accumulator - populating the container with elements of the stream
arr[0] = Math.min(arr[0], next);
arr[1] = Math.max(arr[1], next);
},
(left, right) -> { // combiner - merging containers in parallel
left[0] = Math.min(left[0], right[0]);
left[1] = Math.max(left[1], right[1]);
});
}
main()
public static int[] minMax(int[] sourceArr) {
System.out.println(Arrays.toString(minMax(new int[]{3, 5, -3, 8, 9})));
System.out.println(Arrays.toString(minMax(new int[]{3, -1, 3, 12, 27})));
}
Output:
[-3, 9]
[-1, 27]
But how do I convert an array to an ArrayList?
It's not possible to convert an array of primitives into a List directly. When you have an array of reference type (like Integer, BigDecimal, etc.) you can use Arrays.asList() to fixed-size list wrapped around the given array. But it wouldn't work with primitive arrays.
In order to translate int[] into a List<Integer> you have to create a new list and populate it with the contents of the array.
So your actual goal is to obtain the result as a list, the code provided above might be changed like that:
public static List<Integer> minMax(int[] sourceArr) {
if (sourceArr.length == 0) throw new IllegalArgumentException(); // source array is empty
return Arrays.stream(sourceArr)
.collect(
() -> Arrays.asList(sourceArr[0], sourceArr[0]), // mutable container
(list, next) -> { // accumulator - populating the container with elements of the stream
list.set(0, Math.min(list.get(0), next));
list.set(1, Math.max(list.get(1), next));
},
(left, right) -> { // combiner - merging containers in parallel
left.set(0, Math.min(left.get(0), right.get(0)));
left.set(1, Math.max(left.get(1), right.get(1)));
});
}
I want to sort the elements using Priority Queue in Java.
Here is my code. What is wrong in it?
import java.io.*;
import java.util.*;
class PQ {
static class IntCompare implements Comparator<Integer>{
#Override
public int compare(Integer arg0, Integer arg1) {
if(arg0 > arg1)
return -1;
else if(arg0 < arg1)
return 1;
else
return 0;
}
}
public static void main (String[] args) {
int a[] = { 1, 3, 8, 5, 2, 6 };
Comparator<Integer> c = new IntCompare();
PriorityQueue<Integer> pq=new PriorityQueue<>(c);
for(int i = 0; i < a.length; i++)
pq.add(a[i]);
System.out.println(pq);
}
}
my output is:
8, 5, 6, 1, 2, 3
correct output:
8, 6, 5, 3, 2, 1
When you call System.out.println(pq), the toString method is called implicitly.
The toString method of PriorityQueue extends from AbstractCollection, which
Returns a string representation of this collection. The string
representation consists of a list of the collection's elements in the
order they are returned by its iterator, enclosed in square brackets
("[]").
While the iterator of PriorityQueue is not guaranteed to traverse in particular order:
The Iterator provided in method iterator() is not guaranteed to
traverse the elements of the priority queue in any particular order.
since the queue is based on heap.
You can poll elements one by one to get ordered elements:
while (pq.size() != 0) {
System.out.print(pq.poll() + ","); // 8,6,5,3,2,1,
}
You should poll() all the elements until the queue is empty and save them somewhere to get them ordered.
Try the following, list contains items in sorted order. The priority key by itself not maintain the elements in sorted order, it just keeps the top element as minimum or maximum based on your implementation of the PQ.
public static void main (String[] args) {
int a[]={1,3,8,5,2,6};
Comparator<Integer> c = new IntCompare();
PriorityQueue<Integer> pq=new PriorityQueue<>(c);
for(int i=0;i<a.length;i++)
pq.add(a[i]);
ArrayList<Integer> list = new ArrayList<>();
while(!pq.isEmpty()){
list.add(pq.poll());
}
for(Integer i : list)
System.out.println(i);
}
In R you can do something like this:
> x = c(1, 222, 333, 4, 5)
> x[c(2, 3)]
[1] 222 333
> in the beginning of line is just a prompt in an interactive session. x is a vector of numeric values, and if you want the 2nd and 3rd element of x, you pass another vector c(2, 3) to index x. This is different from Arrays.copyOfRange in java: you can pass an arbitrary index vector to x, not necessarily in a continuous range, i.e. x[c(1,3,5)]
I am wondering if there is a similar feature in java.
As I understood your question, you could create a method that take a list of indexes as parameters.
For generic arrays, you'll need to use Array.newInstance and cast the resulting array to T[] (thanks and kudos for #Radiodef for pointing this out)
//for lists
static <T> List<T> buildList(List<T> original, int... indexes){
List<T> finalList = new ArrayList<>();
for(int index : indexes){
finalList.add(original.get(index));
}
return finalList;
}
//for arrays
static <T> T[] buildArray (T[] original, int... indexes){
#SuppressWarnings("unchecked")
T[] finalArray = (T[])Array.newInstance(original.getClass().getComponentType(), indexes.length);
for(int i = 0; i < indexes.length; i++){
finalArray[i] = original[indexes[i]];
}
return finalArray;
}
Few notes :
For primitive arrays (like int[] or double[]), you'll have to overload the methods, that's why I suggest you to use a List with generics instead.
Indexes for arrays in Java are 0 based (starts from 0 to length-1)
Don't forget to add additional checks for the method (valid index, original list or index not null)
If you use a LinkedList instead of an ArrayList, be aware that #get(int index) is an O(n) operation instead of O(1)
Example of usage :
public static void main(String[] args) {
Integer[] xArray = {-1, 10, 24, 7};
List<Integer> xList = Arrays.asList(-1, 10, 24, 7);
System.out.println(Arrays.toString(buildArray(xArray, 0, 2)));
System.out.println(buildList(xList, 0, 1, 3));
}
Which outputs:
[-1, 24]
[-1, 10, 7]
take a look at Arrays.copyOfRange
Do you know some neat Java libaries that allow you to make cartesian product of two (or more) sets?
For example: I have three sets. One with objects of class Person, second with objects of class Gift and third with objects of class GiftExtension.
I want to generate one set containing all possible triples Person-Gift-GiftExtension.
The number of sets might vary so I cannot do this in nested foreach loop.
Under some conditions my application needs to make a product of Person-Gift pair, sometimes it is triple Person-Gift-GiftExtension, sometimes there might even be sets Person-Gift-GiftExtension-GiftSecondExtension-GiftThirdExtension, etc.
Edit: Previous solutions for two sets removed. See edit history for details.
Here is a way to do it recursively for an arbitrary number of sets:
public static Set<Set<Object>> cartesianProduct(Set<?>... sets) {
if (sets.length < 2)
throw new IllegalArgumentException(
"Can't have a product of fewer than two sets (got " +
sets.length + ")");
return _cartesianProduct(0, sets);
}
private static Set<Set<Object>> _cartesianProduct(int index, Set<?>... sets) {
Set<Set<Object>> ret = new HashSet<Set<Object>>();
if (index == sets.length) {
ret.add(new HashSet<Object>());
} else {
for (Object obj : sets[index]) {
for (Set<Object> set : _cartesianProduct(index+1, sets)) {
set.add(obj);
ret.add(set);
}
}
}
return ret;
}
Note that it is impossible to keep any generic type information with the returned sets. If you knew in advance how many sets you wanted to take the product of, you could define a generic tuple to hold that many elements (for instance Triple<A, B, C>), but there is no way to have an arbitrary number of generic parameters in Java.
This is a pretty old question, but why not use Guava's cartesianProduct?
The method below creates the cartesian product of a list of list of strings:
protected <T> List<List<T>> cartesianProduct(List<List<T>> lists) {
List<List<T>> resultLists = new ArrayList<List<T>>();
if (lists.size() == 0) {
resultLists.add(new ArrayList<T>());
return resultLists;
} else {
List<T> firstList = lists.get(0);
List<List<T>> remainingLists = cartesianProduct(lists.subList(1, lists.size()));
for (T condition : firstList) {
for (List<T> remainingList : remainingLists) {
ArrayList<T> resultList = new ArrayList<T>();
resultList.add(condition);
resultList.addAll(remainingList);
resultLists.add(resultList);
}
}
}
return resultLists;
}
Example:
System.out.println(cartesianProduct(Arrays.asList(Arrays.asList("Apple", "Banana"), Arrays.asList("Red", "Green", "Blue"))));
would yield this:
[[Apple, Red], [Apple, Green], [Apple, Blue], [Banana, Red], [Banana, Green], [Banana, Blue]]
The number of sets might vary so I
cannot do this in nested foreach loop.
Two hints:
A x B x C = A x (B x C)
Recursion
Index-based solution
Working with the indices is an alternative that is fast and memory-efficient and can handle any number of sets. Implementing Iterable allows easy use in a for-each loop. See the #main method for a usage example.
public class CartesianProduct implements Iterable<int[]>, Iterator<int[]> {
private final int[] _lengths;
private final int[] _indices;
private boolean _hasNext = true;
public CartesianProduct(int[] lengths) {
_lengths = lengths;
_indices = new int[lengths.length];
}
public boolean hasNext() {
return _hasNext;
}
public int[] next() {
int[] result = Arrays.copyOf(_indices, _indices.length);
for (int i = _indices.length - 1; i >= 0; i--) {
if (_indices[i] == _lengths[i] - 1) {
_indices[i] = 0;
if (i == 0) {
_hasNext = false;
}
} else {
_indices[i]++;
break;
}
}
return result;
}
public Iterator<int[]> iterator() {
return this;
}
public void remove() {
throw new UnsupportedOperationException();
}
/**
* Usage example. Prints out
*
* <pre>
* [0, 0, 0] a, NANOSECONDS, 1
* [0, 0, 1] a, NANOSECONDS, 2
* [0, 0, 2] a, NANOSECONDS, 3
* [0, 0, 3] a, NANOSECONDS, 4
* [0, 1, 0] a, MICROSECONDS, 1
* [0, 1, 1] a, MICROSECONDS, 2
* [0, 1, 2] a, MICROSECONDS, 3
* [0, 1, 3] a, MICROSECONDS, 4
* [0, 2, 0] a, MILLISECONDS, 1
* [0, 2, 1] a, MILLISECONDS, 2
* [0, 2, 2] a, MILLISECONDS, 3
* [0, 2, 3] a, MILLISECONDS, 4
* [0, 3, 0] a, SECONDS, 1
* [0, 3, 1] a, SECONDS, 2
* [0, 3, 2] a, SECONDS, 3
* [0, 3, 3] a, SECONDS, 4
* [0, 4, 0] a, MINUTES, 1
* [0, 4, 1] a, MINUTES, 2
* ...
* </pre>
*/
public static void main(String[] args) {
String[] list1 = { "a", "b", "c", };
TimeUnit[] list2 = TimeUnit.values();
int[] list3 = new int[] { 1, 2, 3, 4 };
int[] lengths = new int[] { list1.length, list2.length, list3.length };
for (int[] indices : new CartesianProduct(lengths)) {
System.out.println(Arrays.toString(indices) //
+ " " + list1[indices[0]] //
+ ", " + list2[indices[1]] //
+ ", " + list3[indices[2]]);
}
}
}
Here is an Iterable, which allows you to use a simplified for-loop:
import java.util.*;
// let's begin with the demo. Instead of Person and Gift,
// I use the well known char and int.
class CartesianIteratorTest {
public static void main (String[] args) {
List <Object> lc = Arrays.asList (new Object [] {'A', 'B', 'C', 'D'});
List <Object> lC = Arrays.asList (new Object [] {'a', 'b', 'c'});
List <Object> li = Arrays.asList (new Object [] {1, 2, 3, 4});
// sometimes, a generic solution like List <List <String>>
// might be possible to use - typically, a mixture of types is
// the common nominator
List <List <Object>> llo = new ArrayList <List <Object>> ();
llo.add (lc);
llo.add (lC);
llo.add (li);
// Preparing the List of Lists is some work, but then ...
CartesianIterable <Object> ci = new CartesianIterable <Object> (llo);
for (List <Object> lo: ci)
show (lo);
}
public static void show (List <Object> lo) {
System.out.print ("(");
for (Object o: lo)
System.out.print (o + ", ");
System.out.println (")");
}
}
How is it done? We need an Iterable, to use the simplified for-loop, and an Iterator has to be returned from the Iterable.
We return a List of Objects - this could be a Set instead of List, but Set has no indexed access, so it would be a bit more complicated, to implement it with Set instead of List. Instead of a generic solution, Object would have been fine for many purposes, but generics allow for more restrictions.
class CartesianIterator <T> implements Iterator <List <T>> {
private final List <List <T>> lilio;
private int current = 0;
private final long last;
public CartesianIterator (final List <List <T>> llo) {
lilio = llo;
long product = 1L;
for (List <T> lio: lilio)
product *= lio.size ();
last = product;
}
public boolean hasNext () {
return current != last;
}
public List <T> next () {
++current;
return get (current - 1, lilio);
}
public void remove () {
++current;
}
private List<T> get (final int n, final List <List <T>> lili) {
switch (lili.size ())
{
case 0: return new ArrayList <T> (); // no break past return;
default: {
List <T> inner = lili.get (0);
List <T> lo = new ArrayList <T> ();
lo.add (inner.get (n % inner.size ()));
lo.addAll (get (n / inner.size (), lili.subList (1, lili.size ())));
return lo;
}
}
}
}
The mathematical work is done in the 'get'-method. Think about 2 sets of 10 elements. You have a total of 100 combinations, enumerated from 00, 01, 02, ... 10, ... to 99. For 5 X 10 elements 50, for 2 X 3 elements 6 combinations. The modulo of the sublist size helps to pick one element for each iteration.
Iterable i the least interesting thing here:
class CartesianIterable <T> implements Iterable <List <T>> {
private List <List <T>> lilio;
public CartesianIterable (List <List <T>> llo) {
lilio = llo;
}
public Iterator <List <T>> iterator () {
return new CartesianIterator <T> (lilio);
}
}
To implement Iterable, which allows the for-each kind of loop, we have to implement iterator (), and for Iterator we have to implement hasNext (), next () and remove ().
Result:
(A, a, 1, )
(B, a, 1, )
(C, a, 1, )
(D, a, 1, )
(A, b, 1, )
(B, b, 1, )
(C, b, 1, )
(D, b, 1, )
...
(A, a, 2, )
...
(C, c, 4, )
(D, c, 4, )
Here is an Iterator that gives the cartesian product of a two-dimensional array, where the arrays components represent the sets from the question (one can always convert actual Sets to arrays):
public class CartesianIterator<T> implements Iterator<T[]> {
private final T[][] sets;
private final IntFunction<T[]> arrayConstructor;
private int count = 0;
private T[] next = null;
public CartesianIterator(T[][] sets, IntFunction<T[]> arrayConstructor) {
Objects.requireNonNull(sets);
Objects.requireNonNull(arrayConstructor);
this.sets = copySets(sets);
this.arrayConstructor = arrayConstructor;
}
private static <T> T[][] copySets(T[][] sets) {
// If any of the arrays are empty, then the entire iterator is empty.
// This prevents division by zero in `hasNext`.
for (T[] set : sets) {
if (set.length == 0) {
return Arrays.copyOf(sets, 0);
}
}
return sets.clone();
}
#Override
public boolean hasNext() {
if (next != null) {
return true;
}
int tmp = count;
T[] value = arrayConstructor.apply(sets.length);
for (int i = 0; i < value.length; i++) {
T[] set = sets[i];
int radix = set.length;
int index = tmp % radix;
value[i] = set[index];
tmp /= radix;
}
if (tmp != 0) {
// Overflow.
return false;
}
next = value;
count++;
return true;
}
#Override
public T[] next() {
if (!hasNext()) {
throw new NoSuchElementException();
}
T[] tmp = next;
next = null;
return tmp;
}
}
The basic idea is to treat count as a multi-radix number (digit i has its own radix which equals the length of the i'th "set"). Whenever we have to resolve next (that is, when hasNext() is called and next is null), we decompose the number into its digits in this multi-radix. These digits are now used as the indices from which we draw elements from the different sets.
Example use:
String[] a = { "a", "b", "c"};
String[] b = { "X" };
String[] c = { "r", "s" };
String[][] abc = { a, b, c };
Iterable<String[]> it = () -> new CartesianIterator<>(abc, String[]::new);
for (String[] s : it) {
System.out.println(Arrays.toString(s));
}
Output:
[a, X, r]
[b, X, r]
[c, X, r]
[a, X, s]
[b, X, s]
[c, X, s]
If one doesn't like arrays, the code is trivially convertible into using collections.
I guess this is more or less similar to the answer given by "user unknown", only without recursion and collections.
You can get the Cartesian product of an arbitrary number of sets of different types and store it into a set of sets of objects Set<Set<Object>> using Java 9 Streams as follows:
Try it online!
public static Set<Set<Object>> cartesianProduct(Set<?>... sets) {
// incorrect incoming data
if (sets == null) return Collections.emptySet();
return Arrays.stream(sets)
// non-null and non-empty sets
.filter(set -> set != null && set.size() > 0)
// represent each set element as Set<Object>
.map(set -> set.stream().map(Set::<Object>of)
// Stream<Set<Set<Object>>>
.collect(Collectors.toSet()))
// summation of pairs of inner sets
.reduce((set1, set2) -> set1.stream()
// combinations of inner sets
.flatMap(inner1 -> set2.stream()
// merge two inner sets into one
.map(inner2 -> Stream.of(inner1, inner2)
.flatMap(Set::stream)
.collect(Collectors.toCollection(
LinkedHashSet::new))))
// set of combinations
.collect(Collectors.toCollection(LinkedHashSet::new)))
// returns Set<Set<Object>>, otherwise an empty set
.orElse(Collections.emptySet());
}
public static void main(String[] args) {
Set<Integer> set1 = Set.of(1, 2, 3);
Set<String> set2 = Set.of("A", "B", "C");
Set<Object> set3 = Set.of(new Time(0));
Set<Set<Object>> sets = cartesianProduct(set1, set2, set3);
// output
sets.forEach(System.out::println);
}
Output:
[1, A, 03:00:00]
[1, B, 03:00:00]
[1, C, 03:00:00]
[2, A, 03:00:00]
[2, B, 03:00:00]
[2, C, 03:00:00]
[3, A, 03:00:00]
[3, B, 03:00:00]
[3, C, 03:00:00]
See also: How to create a data structure similar to the cartesian product of three lists of different types?
Yes, there is Functional Java.
For a set s:
s.bind(P.p2(), s);
a simple solution, for example, for Integer set should be as follows:
void printCombination(List<Set<Integer>> listSet, Set<Integer> combination) {
if (listSet.isEmpty()) {
System.out.println("a combination :" + combination);
return;
}
Set<Integer> intSet = listSet.get(0);
for (Integer it : intSet) {
Set<Integer> combination1 = new HashSet<Integer>();
combination1.addAll(combination);
combination1.add(it);
List<Set<Integer>> listSet1 = new ArrayList<Set<Integer>>();
listSet1.addAll(listSet);
listSet1.remove(0);
this.printCombination(listSet1, combination1);
}
}
You can apply a simple generator interferace named Seq via this library. Unlike Guava's cartesianProduct, the sets/lists/iterables do not need to be within the same generic type bound B, all types are welcome. And all you need to do is writing the product as normal nested for-loops.
public static void main(String[] args) {
List<String> ls1 = Arrays.asList("a", "b");
List<Integer> ls2 = Arrays.asList(1, 2);
List<Character> ls3 = Arrays.asList('x', 'y');
Seq<String> seq = c -> {
for (String s : ls1) {
for (Integer i : ls2) {
for (Character d : ls3) {
c.accept(s + i + d);
}
}
}
};
System.out.println(seq.toSet());
}
The result would be
[a2x, a1y, b1x, b2y, a1x, a2y, b2x, b1y]
I want to sort an array and find the index of each element in the sorted order.
So for instance if I run this on the array:
[3,2,4]
I'd get:
[1,0,2]
Is there an easy way to do this in Java?
Let's assume your elements are stored in an array.
final int[] arr = // elements you want
List<Integer> indices = new ArrayList<Integer>(arr.length);
for (int i = 0; i < arr.length; i++) {
indices.add(i);
}
Comparator<Integer> comparator = new Comparator<Integer>() {
public int compare(Integer i, Integer j) {
return Integer.compare(arr[i], arr[j]);
}
}
Collections.sort(indices, comparator);
Now indices contains the indices of the array, in their sorted order. You can convert that back to an int[] with a straightforward enough for loop.
import java.util.*;
public class Testing{
public static void main(String[] args){
int[] arr = {3, 2, 4, 6, 5};
TreeMap map = new TreeMap();
for(int i = 0; i < arr.length; i++){
map.put(arr[i], i);
}
System.out.println(Arrays.toString(map.values().toArray()));
}
}
One way to achieve this is to make a list of pairs with the starting index as the second part of the pair. Sort the list of pairs lexicographically, then read off the starting positions from the sorted array.
Starting array:
[3,2,4]
Add pairs with starting indexes:
[(3,0), (2,1), (4,2)]
Sort it lexicographically
[(2,1), (3,0), (4,2)]
then read off the second part of each pair
[1,0,2]
import java.io.*;
public class Sample {
public static void main(String[] args) {
int[] data = {0, 3, 2, 4, 6, 5, 10};//case:range 0 - 10
int i, rangeHigh = 10;
int [] rank = new int[rangeHigh + 1];
//counting sort
for(i=0; i< data.length ;++i) ++rank[data[i]];
for(i=1; i< rank.length;++i) rank[i] += rank[i-1];
for(i=0;i<data.length;++i)
System.out.print((rank[data[i]]-1) + " ");//0 2 1 3 5 4 6
}
}
As an update, this is relatively easy to do in Java 8 using the streams API.
public static int[] sortedPermutation(final int[] items) {
return IntStream.range(0, items.length)
.mapToObj(value -> Integer.valueOf(value))
.sorted((i1, i2) -> Integer.compare(items[i1], items[i2]))
.mapToInt(value -> value.intValue())
.toArray();
}
It somewhat unfortunately requires a boxing and unboxing step for the indices, as there is no .sorted(IntComparator) method on IntStream, or even an IntComparator functional interface for that matter.
To generalize to a List of Comparable objects is pretty straightforward:
public static <K extends Comparable <? super K>> int[] sortedPermutation(final List<K> items) {
return IntStream.range(0, items.size())
.mapToObj(value -> Integer.valueOf(value))
.sorted((i1, i2) -> items.get(i1).compareTo(items.get(i2)))
.mapToInt(value -> value.intValue())
.toArray();
}