Now this the question am trying to answer:
Write a method which takes a sparse array as an argument and returns
a new equivalent dense array.The dense array only needs to be large enough to fit all of the values.For example,the resulting dense array only needs to hold 90 values if the last element in the sparse array is at index 89.
dense array:[3,8,4,7,9,0,5,0] the number are generated randomly.
sparse array is an arraylist of arrays [[0,3],[1,8],[2,4],[3,7],[4,9],[6,5]]
so in the sparse array if the number generated is !0 the value and its index are stored in array of size 2 but if the number generated is 0 nothing is stored
When you have a fixed size for element (as array) in your collection. Your solution is OK and that is a fast way.
But when your element does not have a fixed size, such as: [[1,2,3],[4,5],[6],[7,8,9,10,11]] so you can interator through your element:
for(int[] e : sparseArr)
{
for(int number : e)
{
tree.add(number);
}
}
No matter how many element in your sparseArr, no how long of your element>
To sort your element, I recommend you should use TreeSet<E>, element push into tree will be sorted automatically.
So if you just want to store 2 Integers paired together I recommend going with HashMaps. In your case you would use:
HashMap<Integer, Integer> map = new HashMap<Integer, Integer>();
HashMaps support .containsKey(key); as well as .containsValue(value);
If you want to check all entries you can transform the Map to an entrySet:
for(Entry<Integer, Integer> e : map.entrySet()) {
int one = e.getKey();
int two = e.getValue();
}
Unless you want to do something more special than just storing 2 paired Integers I really can recommend doing it this way!
The method you're after should do something like this
public int[] sparseToDense (ArrayList<int[]> sparse) {
int i = 0;
int[] dense = new int[sparse.get(sparse.size()-1)[0]];
int[] sp;
ListIterator<int[]> iter = sparse.listIterator();
while (iter.hasNext()) {
sp = iter.next();
while (sp[0] != i) {
dense[i++] = 0;
}
dense[i++] = sp[1];
}
return dense;
}
Just another way to do that, since you have java 8, you will be able to use stream. But if you're a beginner, i recommend you to try with for loops and arrays, will be better for your learning.
public static ArrayList<Integer> returnDense(ArrayList<int[]> sparse) {
return sparse.stream().flatMap(p -> IntStream.of(p).boxed())
.collect(Collectors.toCollection(ArrayList::new));
}
also if you decide change int[] to Integer[].
public ArrayList<Integer> returnDense(ArrayList<Integer[]> sparse) {
return sparse.stream().flatMap(p -> Arrays.asList(p).stream()).filter(Objects::nonNull)
.collect(Collectors.toCollection(ArrayList::new));
}
.filter(Objects::nonNull) is to be sure that will not have nulls values, but if you know that will not have it, that isn't necessary.
Related
Its a very trivial question and related to coding Style and I am just asking to make my coding style more readable
Suppose I have a Collection like linkedList and an Array and I need to iterate over both simultaneously.
currently the best way I know is to get a iterator over list and define a index variable outside the iterator loop and increment the index variable simultaneously to access both next elements {list and array}. Please refer the example below
LinkedList<Integer> list = new LinkedList<Integer>();
Integer[] arr = new Array[25];
// lets suppose both have 25 elements.
// My Iteration method will be
int index =0;
for (Integer val : list) {
System.out.println(val);
System.out.println(arr[index++]);
}
so is it the only way or is there any other way I can perform this iteration in more readable and more relatable manner, where I don't have to take index variable separately.
I know it can be possible that array might have less or more elements than collection but I am only talking about the cases where they have equal and we need to iterate over Both of them.
PS : anybody can write a code that a computer can understand, actual challenge is to write code which humans can understand easily.
What you have is essentially fine: it's simple, and simple can be sufficient to make code readable.
The only thing I would caution about is the side effect of index++ inside arr[index++]: if, say, you want to use the same value multiple times in the loop body, you couldn't simply copy+paste.
Consider pulling out a variable as the first thing in the loop to store the "current" array element (which is essentially what the enhanced for loop does for the list element).
for (Integer val : list) {
Integer fromArr = arr[index++];
// ...
}
Just to point out an alternative without having a separate variable for the index, you can use ListIterator, which provides you with the index of the element.
// Assuming list and are have same number of elements.
for (ListIterator<Integer> it = list.listIterator();
it.hasNext();) {
// The ordering of these statements is important, because next() changes nextIndex().
Integer fromArr = arr[it.nextIndex()];
Integer val = it.next();
// ...
}
ListIterator is not an especially widely-used class, though; its use may in and of itself be confusing.
One of the downsides of the ListIterator approach is that you have to use the it correctly: you shouldn't touch it inside the loop (after getting the values), you have to put the statements in the right order, etc.
Another approach would be to create a library method analogous to Python's enumerate:
static <T> Iterable<Map.Entry<Integer, T>> enumerate(Iterable<? extends T> iterable) {
return () -> new Iterator<T>() {
int index = 0;
Iterator<? extends T> delegate = iterable.iterator();
#Override public boolean hasNext() { return delegate.hasNext(); }
#Override public Map.Entry<Integer, T> next() {
return new AbstractMap.SimpleEntry<>(index++, delegate.next());
}
};
}
This returns an iterable of map entries, where the key is the index and the value is the corresponding value.
You could then use this in an enhanced for loop:
for (Map.Entry<Integer, Integer> entry : enumerate(list)) {
Integer fromList = entry.getValue();
Integer fromArr = arr[entry.getKey()];
}
One option is to have 2 iterators, but I don't think it is any clearer:
for (Iterator<Integer> i1 = list.iterator(), i2 = Arrays.asList(arr).iterator();
i1.hasNext() && i2.hasNext();) {
System.out.println(i1.next());
System.out.println(i2.next());
}
But it is more robust in that it finishes at the shorter of the 2 collections.
I tried to simplify and handle size wise collections where both need not be of the same size. I believe this would work even if the sizes are not same and just one loop would suffice. Code snippet below:
LinkedList<Integer> list = new LinkedList<Integer>();
Integer[] arr = new Array[25];
int maxLength= Math.max(list.size(),arr.size());
//Looping over the lengthy collection( could be Linkedlist or arraylist)
for(int i=0;i<maxLength;i++){
if(list.size()>i)
System.out.println(list[i]);
if(arr.size()>i)
System.out.println(arr[i]);
}
Hope this helps! Thanks
I have sorted List<Pair<Integer, Integer>> and I want to create a subList for all the Pairs which having a key less than one arbitrary value k.
I want to create a subList that follows above condition and sort it.
I did something like this -
//to get the max index of the List
public static int getIndex(List<Pair<Integer,Integer>> list,int key)
{
int count=0;
for(Pair<Integer,Integer> p: list)
{
if(p.getKey()>key)
break;
count++;
}
return count;
}
Now, Sorting subList as per this criteria
int count = getIndex(current.getValue(),list);
Collections.sort(list.subList(0, count),Comparator.<Pair<Integer,Integer>>comparingInt(Pair::getValue));
Is there any elegent way to do achieve this ? I mean java 8 way.
Stream API came into my mind. But after performing operations it doesn't manipulate the underlined collection.
Something like the following.
List<Pair<Integer,Integer>> subList =
list.stream()
.filter(p->p.getKey() < key)
.collect(Collectors.toList());
This works regardless of the ordering of the pairs in the list. It constructs the new list as each pair passes thru the filter.
This question already has answers here:
Sort a parallel array using Arrays.sort()
(5 answers)
Closed 6 years ago.
Using Arrays.sort( array ); is a very easy way to sort an array. But there is a problem. For each unsorted array, there is an index which is referring to an object in some other data structure. When sorting an array (using the above code or any other similar ways) the index of each value will be changed. Is there a solution to have the assigned index of each value?
EDIT
Using HashMap<Key, Value> will not be useful since there are a lot of same values in the array.
Sort both data structures in parallel.
Or make the reference index (to reference the other data structure) an internal field of each element, so that each element maintains the same "reference index" even if the order of the elements is changed by sorting.
Or better yet, just give each element an internal field that is just a direct reference variable to the element in the other data structure. (unless you need the raw index itself for some reason and not just a reference to the associated object / value)
For example: this SO Q&A
First, having two parallel arrays with elements in corresponding indexes indicates you might want to change the data structure to a single array with a container object containing two fields. This container object would then implement Comparable interface.
But, sticking with what you say, one approach could be:
/**
* Sorts parallel arrays in-place. Sorted by the first array and updating
* all other arrays to match.
* Uses the natural sorting of the objects.
* All arrays must be the same length.
*
* #param keys the values used to sort, may be duplicate
*
* #param otherArrays the arrays to have reordered to match the sorting of
* the keys array.
*
* #exception IllegalArgumentException if any of otherArrays have a length
* different that the keys array.
*/
public static <E extends Comparable<? super E>> void sortParallelArrays(
E[] keys,
Object[] ... otherArrays
) {
int numKeys = keys.length;
int numOtherArrays = otherArrays.length;
for(Object[] otherArray : otherArrays) {
if(otherArray.length != numKeys) {
throw new IllegalArgumentException("Mismatched array lengths");
}
}
// A list of all indexes per key
// This also does the sorting within the TreeMap using natural ordering
SortedMap<E, List<Integer>> originalIndexesByKey = new TreeMap<E, List<Integer>>();
// Populate the map
for(int i = 0; i < numKeys; i++) {
E key = keys[i];
List<Integer> originalIndexes = originalIndexesByKey.get(key);
if(originalIndexes == null) {
// Optimization for the non-duplicate keys
originalIndexesByKey.put(key, Collections.singletonList(i));
} else {
if(originalIndexes.size() == 1) {
// Upgrade to ArrayList now that know have duplicate keys
originalIndexes = new ArrayList<Integer>(originalIndexes);
originalIndexesByKey.put(key, originalIndexes);
}
originalIndexes.add(i);
}
}
// Store back to keys and sort other arrays in a single traversal
Object[][] sortedOtherArrays = new Object[numOtherArrays][numKeys];
int pos = 0;
for(Map.Entry<E, List<Integer>> entry : originalIndexesByKey.entrySet()) {
E key = entry.getKey();
for(int index : entry.getValue()) {
keys[pos] = key;
for(int ooIndex = 0; ooIndex < numOtherArrays; ooIndex++) {
sortedOtherArrays[ooIndex][pos] = otherArrays[ooIndex][index];
}
pos++;
}
}
assert pos == numKeys : "Arrays should be full";
// Copy back to original arrays for in-place sort
for(int ooIndex = 0; ooIndex < numOtherArrays; ooIndex++) {
System.arraycopy(
sortedOtherArrays[ooIndex], 0,
otherArrays[ooIndex], 0,
numKeys);
}
}
This is not the most memory efficient strategy, but isn't much code.
The time complexity isn't too bad. Looks something like O((M+1)*N*log(N)), where M is the number of otherArrays and N is the number of keys. No crazy worst-case issues, at least.
I want to make arrayList object in java that work as two dimentional array. My question is how can we access value from specific dimention from arrayList.
in two dimentional array, if i want to access value then it can be as m[i][j].
But in arraylist how can i do that ?
You mean something like a List in a List??
May be something like...
List<List<...>> twoDList = new ArrayList<>();
i want to make a List, in which each List key contains another List inside it
It should more like you want some kind of Map, which is basically a key/value pair.
Map<String, List<String>> mapValues = new HashMap<>(25);
List<String> listOfValues = ...;
//...
mapValues.put("A unique key for this list", listOfValues);
//...
List<String> thatListOfValues = mapValues.get("A unique key for this list");
List<List<Integer>> list = new ArrayList<List<Integer>>();
list.add(new ArrayList<Integer>());
list.add(new ArrayList<Integer>());
list.get(0).add(5);
list.get(1).add(6);
for(List<Integer> listiter : list)
{
for(Integer integer : listiter)
{
System.out.println("" + integer);
}
}
This way you can get the items like
list.get(1).get(0); //second dimension list -> integer
EDIT:
Although it is true that you can use a Map if you are trying to use numeric indices for example for each list, like so:
Map<Integer, List<YourObject>> map = new HashMap<Integer, List<YourObject>>();
map.put(0, new ArrayList<YourObject>());
map.put(5, new ArrayList<YourObject>());
map.get(0).add(new YourObject("Hello"));
map.get(5).add(new YourObject("World"));
for(Integer integer : map.keySet())
{
for(YourObject yourObject : map.get(integer))
{
yourObject.print(); //example method
System.out.println(" ");
}
}
Although even then the accessing of Lists would be the same as before,
map.get(0).get(1); //List -> value at index
Obviously you don't need to use Integers as the generic type parameter, that's just a placeholder type.
The solution like List<List<..>> is slow then you should use one dimention array like
// Two dimentions: m and n
List<String> arr = new ArrayList<String>(m*n);
for (int i=0; i< m; ++i) {
for (int j=0; j<n; ++j) {
String str=arr.get(i*n + j);
//You code here
}
}
Memory is an important consideration here.
It can be acceptable to model a 2D (or higher dimension) array using a 1D container. (This is how the VARIANT SAFEARRAY of Microsoft's COM works.) But, consider this carefully if the number of elements is large; especially if the container allocates a contiguous memory block. Using something like List<List<... will model a jagged-edged matrix and can fragment your memory.
With the 1D approach, you can use the get(index) method on the ArrayList appropriately transformed:
Given the (i)th row and (j)th column, transform using index = i * rows + j where rows is the number of rows in your matrix.
An arraylist is not an object to make a 2 dimentional arrays. However you can use it anyway :
You can use :
new ArrayList<ArrayList<Object>>; //or
new ArrayList<Object[]>;
But you should implement your own matrix class because you will probably have some check to do and a function get(int row, int column) would be cool
Also consider Table collection provided by Google Guava library. ArrayTable is an implementation based on 2D array.
You cane define like this
1>
List<Object[]> list = new ArrayList<Object[]>();
Fetching
list.get(i)[j];
2>
List<Map<Integer,Object>> list = new ArrayList<Map<Integer,Object>>();
Fetching
list.get(i).get(j);
In PHP, you can dynamically add elements to arrays by the following:
$x = new Array();
$x[] = 1;
$x[] = 2;
After this, $x would be an array like this: {1,2}.
Is there a way to do something similar in Java?
Look at java.util.LinkedList or java.util.ArrayList
List<Integer> x = new ArrayList<Integer>();
x.add(1);
x.add(2);
Arrays in Java have a fixed size, so you can't "add something at the end" as you could do in PHP.
A bit similar to the PHP behaviour is this:
int[] addElement(int[] org, int added) {
int[] result = Arrays.copyOf(org, org.length +1);
result[org.length] = added;
return result;
}
Then you can write:
x = new int[0];
x = addElement(x, 1);
x = addElement(x, 2);
System.out.println(Arrays.toString(x));
But this scheme is horribly inefficient for larger arrays, as it makes a copy of the whole array each time. (And it is in fact not completely equivalent to PHP, since your old arrays stays the same).
The PHP arrays are in fact quite the same as a Java HashMap with an added "max key", so it would know which key to use next, and a strange iteration order (and a strange equivalence relation between Integer keys and some Strings). But for simple indexed collections, better use a List in Java, like the other answerers proposed.
If you want to avoid using List because of the overhead of wrapping every int in an Integer, consider using reimplementations of collections for primitive types, which use arrays internally, but will not do a copy on every change, only when the internal array is full (just like ArrayList). (One quickly googled example is this IntList class.)
Guava contains methods creating such wrappers in Ints.asList, Longs.asList, etc.
Apache Commons has an ArrayUtils implementation to add an element at the end of the new array:
/** Copies the given array and adds the given element at the end of the new array. */
public static <T> T[] add(T[] array, T element)
I have seen this question very often in the web and in my opinion, many people with high reputation did not answer these questions properly. So I would like to express my own answer here.
First we should consider there is a difference between array and arraylist.
The question asks for adding an element to an array, and not ArrayList
The answer is quite simple. It can be done in 3 steps.
Convert array to an arraylist
Add element to the arrayList
Convert back the new arrayList to the array
Here is the simple picture of it
And finally here is the code:
Step 1:
public List<String> convertArrayToList(String[] array){
List<String> stringList = new ArrayList<String>(Arrays.asList(array));
return stringList;
}
Step 2:
public List<String> addToList(String element,List<String> list){
list.add(element);
return list;
}
Step 3:
public String[] convertListToArray(List<String> list){
String[] ins = (String[])list.toArray(new String[list.size()]);
return ins;
}
Step 4
public String[] addNewItemToArray(String element,String [] array){
List<String> list = convertArrayToList(array);
list= addToList(element,list);
return convertListToArray(list);
}
You can use an ArrayList and then use the toArray() method. But depending on what you are doing, you might not even need an array at all. Look into seeing if Lists are more what you want.
See: Java List Tutorial
You probably want to use an ArrayList for this -- for a dynamically sized array like structure.
You can dynamically add elements to an array using Collection Frameworks in JAVA. collection Framework doesn't work on primitive data types.
This Collection framework will be available in "java.util.*" package
For example if you use ArrayList,
Create an object to it and then add number of elements (any type like String, Integer ...etc)
ArrayList a = new ArrayList();
a.add("suman");
a.add(new Integer(3));
a.add("gurram");
Now you were added 3 elements to an array.
if you want to remove any of added elements
a.remove("suman");
again if you want to add any element
a.add("Gurram");
So the array size is incresing / decreasing dynamically..
Use an ArrayList or juggle to arrays to auto increment the array size.
keep a count of where you are in the primitive array
class recordStuff extends Thread
{
double[] aListOfDoubles;
int i = 0;
void run()
{
double newData;
newData = getNewData(); // gets data from somewhere
aListofDoubles[i] = newData; // adds it to the primitive array of doubles
i++ // increments the counter for the next pass
System.out.println("mode: " + doStuff());
}
void doStuff()
{
// Calculate the mode of the double[] array
for (int i = 0; i < aListOfDoubles.length; i++)
{
int count = 0;
for (int j = 0; j < aListOfDoubles.length; j++)
{
if (a[j] == a[i]) count++;
}
if (count > maxCount)
{
maxCount = count;
maxValue = aListOfDoubles[i];
}
}
return maxValue;
}
}
This is a simple way to add to an array in java. I used a second array to store my original array, and then added one more element to it. After that I passed that array back to the original one.
int [] test = {12,22,33};
int [] test2= new int[test.length+1];
int m=5;int mz=0;
for ( int test3: test)
{
test2[mz]=test3; mz++;
}
test2[mz++]=m;
test=test2;
for ( int test3: test)
{
System.out.println(test3);
}
In Java size of array is fixed , but you can add elements dynamically to a fixed sized array using its index and for loop. Please find example below.
package simplejava;
import java.util.Arrays;
/**
*
* #author sashant
*/
public class SimpleJava {
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
// TODO code application logic here
try{
String[] transactions;
transactions = new String[10];
for(int i = 0; i < transactions.length; i++){
transactions[i] = "transaction - "+Integer.toString(i);
}
System.out.println(Arrays.toString(transactions));
}catch(Exception exc){
System.out.println(exc.getMessage());
System.out.println(Arrays.toString(exc.getStackTrace()));
}
}
}