I have an ArrayList named play_viewCount: I am sorting this ArrryList and storing it in a new ArrayList.
Now I have sorted ArrayList: but what I want is before sorting what was the position of new items in ArrayList?
ArrayList<String> sort_play_viewCount = play_ViewCount; // here play_viewCount is ArrayList
ArrayList<Integer> position_array = new ArrayList<Integer>();
System.out.println("......................................... Play Count :"+sort_play_viewCount);
Collections.sort(sort_play_viewCount);
System.out.println(".........................................sort Play Count :"+sort_play_viewCount);
for(int j = 0; j<sort_play_viewCount.size(); j++){
for(int k = 0; k<sort_play_viewCount.size(); k++){
if(play_ViewCount.contains(sort_play_viewCount.get(j))){
position_array.add(k);
}
}
}
System.out.println(" .................Position Array: "+position_array);
Does anyone know how to get the positions of the new items before sorting?
Try doing a little differently:
ArrayList<Integer> position_array = new ArrayList<Integer>();
position_array.addAll(play_viewCount);
Collections.sort(position_array);
Now position_array is sorted, and to get the previous positions you can just call play_viewCount.indexOf(value);
You can put the elements of the ArrayList into a Map<String, Integer> (implemented by a HashMap<String, Integer>), where the key of an entry is String element from the ArrayList and the value is Integer representing the position.
Map<String, Integer> originalPositions = new HashMap<String, Integer>();
String item = ...
String position = ...
originalPositions.put(item, position);
// do something with the ArrayList, such as sorting
Collections.sort(arrayList);
String someItem = arrayList.get(i);
int originalPosition = originalPositions.get(someItem);
And by the way, this line from your code snippet doesn't do what you think it does:
ArrayList<String> sort_play_viewCount = play_ViewCount;
It doesn't create a new ArrayList with the same contents as the original one. Instead, it just creates a new reference to the original ArrayList. Both play_ViewCount and sort_play_viewCount refer to the very same object, in other words, any changes to one of the variables (such as sorting) also affect the other one.
To create a new copy (however, it is still shallow) of an ArrayList, use the following idiom:
ArrayList<Integer> original = ...
ArrayList<Integer> copy = new ArrayList<Integer>(original);
Related
I have a problem where I want to keep the original arraylist and want to make two separate arraylist where one doesn't contain any duplicates and the other the amount of items in the first arraylist.
For example:
ArrayList<Item> items = new ArrayList<Item>();
ArrayList<Item> items2 = new ArrayList<Item>();
ArrayList<Item> occurences = new ArrayList<Item>();
items[0, 1, 2] would have bandana bandana bandana
items2[0] would have bandana
occurences[0] would have 3
Below code shows an example of what you need but instead of Item (I don't know if you put it as example or it's your class) there are String to store elements and Integer for occurences.
To store elements without duplicates I suggest to use Set
public static void main(String[] args) {
ArrayList<String> items = new ArrayList<String>();
ArrayList<String> items2 = new ArrayList<String>();
ArrayList<Integer> occurences = new ArrayList<Integer>();
items.add("bandana");
items.add("bandana");
items.add("bandana");
items2.addAll(new HashSet<>(items)); // create Hashset to remove duplicates and add again to Arraylist
occurences.add(items.size()); // add size of items list as first element
items.forEach(System.out::println); // Print: "bandana" "bandana" "bandana"
items2.forEach(System.out::println); // Print: "bandana"
occurences.forEach(System.out::println); // Print: 1
}
This is probably not the most efficient way of doing it but I would try something like this:
ArrayList<Item> items = new ArrayList<Item>();
ArrayList<Item> items2 = new ArrayList<Item>();
ArrayList<Item> occurences = new ArrayList<Item>();
for(int i=0; i<items.size(); i++)
{
Item x = items.get(i);
int count=1;
if(!items2.contains(x))
{
items2.add(x);
for(int j=i+1; j<items.size(); j++)
{
if(items2.get(j)==x)
count++;
}
ocurrences.add(count);
}
}
You might want to change Item to int for the occurrences list.
No Duplicates in Collection
For the collection that should have no duplicate Items, use a Set<Item> instead of an ArrayList<Item>. The Set data structure will not store duplicates. Since Item is a custom object you created, you will need to override the hashCode and equals method in your Item class.
This approach is O(1) - which is way better than keep an ArrayList<Item> and iterating it and searching for a duplicate (which will be O(n) at worst).
Occurrences
For the occurrences problem, instead of keeping your items in an ArrayList<Item>, keep them in a Map<Item,Integer>. This will map the item to how many occurrences there are of it.
Using the map, you will need to get the key, which is the Item you are about to add. If it already exists in the map, simply add one to the value of that key (the occurrences number).
If they key doesn't exist yet (this is the first time this Item will be inserted into the map), simply add it to the map, and set the value as 1.
Using a map will also be a way more efficient solution, as it will also be O(1), instead of O(n) if an ArrayList<Item> will be used.
Example:
Set<Item> itemSet = new HashSet<>();
Map<Item,Integer> occurencesMap = new HashMap<>();
itemSet.add(yourItem);
itemSet.add(yourItem);
itemSet.add(secondItem);
//itemSet now contains only 2 objects!
if (occurencesMap.get(yourItem) == null){
occurencesMap.put(yourItem,1);
}
else{
//adding 1 to the current value of occurences for that item.
occurencesMap.get(yourItem)++;
}
This is my solution using streams and lambda functions. I moddified occurence to be a Map<Item, Integer> so that we can count per item
items.stream().forEach( i -> {
if (!items2.contains(i)) {
items2.add(i);
}
occurences.merge(i, 1, Integer::sum);
});
The very cool use of merge was found in this answer. Since we don't know what Item i I tested this using String instead so equals etc worked properly
Using lambdas to get a list of distinct values:
ArrayList items2 = items.stream().distinct().collect(Collectors.toCollection(ArrayList::new)));
If I understood correctly you need the number of occurrences for each item:
Map<Item, Integer> m = new HashMap();
items.stream().forEach(k-> m.merge(k,1, Integer::sum));
ArrayList occurrences = new ArrayList(m.values());
The order in occurrences does not reflect the order of the items.
You can generate each list as below,
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.LinkedHashSet;
public class Main
{
public static void main(String args[])
{
ArrayList<String> items = new ArrayList<>();
ArrayList<String> items2 = new ArrayList<>();
ArrayList<Integer> occurrences = new ArrayList<>();
items.addAll(Arrays.asList("bandana", "bandana", "bandana", "abc", "abc"));
items2.addAll(new LinkedHashSet<>(items));
for (String item : items2)
{
occurrences.add(Collections.frequency(items, item));
}
System.out.println(items);
System.out.println(items2);
System.out.println(occurrences);
}
}
Assuming you can use Java 8 streams you could also do it this way:
List<String> items = Arrays.asList("bandana", "helmet", "bandana",
"bandana", "silk hat", "basecap", "silk hat");
Map<String, Long> result = items.stream().collect(
Collectors.groupingBy(Function.identity(), Collectors.counting()));
System.out.println(result); //prints {silk hat=2, helmet=1, bandana=3, basecap=1}
Instead of two lists with the distinct values and the occurences you will have a map with the item itself as key (Function.identity()) and the number of occurences as the value (Collectors.counting()).
I have the following code which surprisingly doesn't work;
needsInfoView = (ListView) findViewById(R.id.needsInfo);
needsInfoList = new ArrayList<>();
HashMap<String, String> needsInfoHashMap = new HashMap<>();
for (int i = 0; i < 11; i++) {
needsInfoHashMap.put("TA", needsTitleArray[i]);
needsInfoHashMap.put("IA", needsInfoArray[i]);
Log.e("NIMH",needsInfoHashMap.toString());
//Here, I get the perfect output - TA's value, then IA's value
needsInfoList.add(needsInfoHashMap);
Log.e("NIL",needsInfoList.toString());
//This is a mess - TA, IA values for 12 entries are all the same, they are the LAST entries of needsTitleArray and needsInfoArray on each ArrayList item.
needsInfoAdapter = new SimpleAdapter(getBaseContext(), needsInfoList,
R.layout.needsinfocontent, new String[]{ "TA", "IA"},
new int[]{R.id.ta, R.id.ia});
needsInfoView.setVerticalScrollBarEnabled(true);
needsInfoView.setAdapter(needsInfoAdapter);
}
Please see the comment below the log lines. That explains the output I receive. How do I make the ArrayList values pass to the two text fields in my ListView via the SimpleAdapter?
Thank you
For loop of Hashmap to ArrayList is not holding the correct values
Because your are adding same instance HashMap in your needsInfoList
You need to add new instance HashMap in your needsInfoList list like below code
Also you need to set your needsInfoAdapter to your needsInfoView listview outside the loop like below code
Try this
needsInfoList = new ArrayList<>();
needsInfoView = (ListView) findViewById(R.id.needsInfo);
for (int i = 0; i < 11; i++) {
HashMap<String, String> needsInfoHashMap = new HashMap<>();
needsInfoHashMap.put("TA", needsTitleArray[i]);
needsInfoHashMap.put("IA", needsInfoArray[i]);
needsInfoList.add(needsInfoHashMap);
}
needsInfoAdapter = new SimpleAdapter(getBaseContext(), needsInfoList,
R.layout.needsinfocontent, new String[]{"TA", "IA"},
new int[]{R.id.ta, R.id.ia});
needsInfoView.setVerticalScrollBarEnabled(true);
needsInfoView.setAdapter(needsInfoAdapter);
You are adding the same HashMap instance multiple times to the List, which means the entries you put in the Map on each iteration replace the entries put by the previous iteration.
You should create a new HashMap instance on each iteration:
for (int i = 0; i < 11; i++) {
HashMap<String, String> needsInfoHashMap = new HashMap<>();
needsInfoHashMap.put("TA", needsTitleArray[i]);
needsInfoHashMap.put("IA", needsInfoArray[i]);
needsInfoList.add(needsInfoHashMap);
....
}
I need a Array to PayPal Items must however go another arraylist to add the items as I do that?
ArrayList<PayPalItem[]> stringArrayList = new ArrayList<PayPalItem[]>();
for (int i=0; i<resultado.size(); i++) {
PayPalItem[] items;
double x = Math.round(((resultado.get(i).getTotal() / resultado.get(i).getPreco())));
int quantidade = (int) x;
String preco = String.format("%.2f", resultado.get(i).getPreco());
String nome = resultado.get(i).getProduto();
items = new PayPalItem[]{
new PayPalItem(nome, quantidade, new BigDecimal(resultado.get(i).getPreco()), "BRL",
"dinner")
};
stringArrayList.add(items); //add to arraylist
}
PayPalItem[] items = new PayPalItem[stringArrayList.size()];
//if you want your array
PayPalItem[] stringArray = stringArrayList.toArray(items);
I'm trying to convert an ArrayList to the Array however I get this error
Conversion from an arrayList i.e. ArrayList<Something> list to an Array is done this way (as you already did):
list.toArray(Something[]) <- notice that the parameter here is an array of Something elements.
so in your case: Something is PayPalItem[] then you need to add an extra [] because you have an array of arrays.
replacing your last two lines of your code by these two will solve your issue.
PayPalItem[][] items = new PayPalItem[stringArrayList.size()][];
//if you want your array
PayPalItem[][] stringArray = stringArrayList.toArray(items);
but anyway, I cannot understand why do you need an array of arrays instead of simply just a list or an array. I mean something like this:
ArrayList<PayPalItem> stringArrayList = new ArrayList<PayPalItem>();
for (int i = 0; i < 2; i++) {
//create the PayPalItem and add to the list
stringArrayList.add(new PayPalItem()); //add to arraylist
}
PayPalItem[] items = new PayPalItem[stringArrayList.size()];
//if you want your array
PayPalItem[] stringArray = stringArrayList.toArray(items);
I have 3 arraylist each have size = 3 and 3 arrays also have length = 3 of each. I want to copy data from arraylists to arrays in following way but using any loop (i.e for OR for each).
myArray1[1] = arraylist1.get(1);
myArray1[2] = arraylist2.get(1);
myArray1[3] = arraylist3.get(1);
I have done it manually one by one without using any loop, but code appears to be massive because in future I'm sure that number of my arraylists and arrays will increase up to 15.
I want to copy the data from arraylists to arrays as shown in the image but using the loops not manually one by one?
How about this?
List<Integer> arraylist0 = Arrays.asList(2,4,3);
List<Integer> arraylist1 = Arrays.asList(2,5,7);
List<Integer> arraylist2 = Arrays.asList(6,3,7);
List<List<Integer>> arraylistList = Arrays.asList(arraylist0, arraylist1, arraylist2);
int size = 3;
int[] myArray0 = new int[size];
int[] myArray1 = new int[size];
int[] myArray2 = new int[size];
int[][] myBigArray = new int[][] {myArray0, myArray1, myArray2};
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
myBigArray[i][j] = arraylistList.get(j).get(i);
}
}
To explain, since we want to be able to work with an arbitrary size (3, 15, or more), we are dealing with 2-dimensional data.
We are also dealing with array and List, which are slightly different in their use.
The input to your problem is List<Integer>, and so we make a List<List<Integer>> in order to deal with all the input data easily.
Similarly, the output will be arrays, so we make a 2-dimensional array (int[][]) in order to write the data easily.
Then it's simply a matter of iterating over the data in 2 nested for loops. Notice that this line reverses the order of i and j in order to splice the data the way you intend.
myBigArray[i][j] = arraylistList.get(j).get(i);
And then you can print your answer like this:
System.out.println(Arrays.toString(myArray0));
System.out.println(Arrays.toString(myArray1));
System.out.println(Arrays.toString(myArray2));
You need to have two additional structures:
int[][] destination = new int [][] {myArray1, myArray2,myArray3 }
List<Integer>[] source;
source = new List<Integer>[] {arraylist1,arraylist2,arraylist3}
myArray1[1] = arraylist1.get(1);
myArray1[2] = arraylist2.get(1);
myArray1[3] = arraylist3.get(1);
for (int i=0;i<destination.length;i++) {
for (int j=0;j<source.length;j++) {
destination[i][j] = source[j].get(i);
}
}
If you cannot find a ready made API or function for this, I would suggest trivializing the conversion from List to Array using the List.toArray() method and focus on converting/transforming the given set of lists to a another bunch of lists which contain the desired output. Following is a code sample which I would think achieves this. It does assume the input lists are NOT of fixed/same sizes. Assuming this would only make the logic easier.
On return of this function, all you need to do is to iterate over the TreeMap and convert the values to arrays using List.toArray().
public static TreeMap<Integer, List<Integer>> transorm(
List<Integer>... lists) {
// Return a blank TreeMap if not input. TreeMap explanation below.
if (lists == null || lists.length == 0)
return new TreeMap<>();
// Get Iterators for the input lists
List<Iterator<Integer>> iterators = new ArrayList<>();
for (List<Integer> list : lists) {
iterators.add(list.iterator());
}
// Initialize Return. We return a TreeMap, where the key indicates which
// position's integer values are present in the list which is the value
// of this key. Converting the lists to arrays is trivial using the
// List.toArray() method.
TreeMap<Integer, List<Integer>> transformedLists = new TreeMap<>();
// Variable maintaining the position for which values are being
// collected. See below.
int currPosition = 0;
// Variable which keeps track of the index of the iterator currently
// driving the iteration and the driving iterator.
int driverItrIndex = 0;
Iterator<Integer> driverItr = lists[driverItrIndex].iterator();
// Actual code that does the transformation.
while (driverItrIndex < iterators.size()) {
// Move to next driving iterator
if (!driverItr.hasNext()) {
driverItrIndex++;
driverItr = iterators.get(driverItrIndex);
continue;
}
// Construct Transformed List
ArrayList<Integer> transformedList = new ArrayList<>();
for (Iterator<Integer> iterator : iterators) {
if (iterator.hasNext()) {
transformedList.add(iterator.next());
}
}
// Add to return
transformedLists.put(currPosition, transformedList);
}
// Return Value
return transformedLists;
}
Please help me to convert ArrayList to String[]. The ArrayList contains values of type Object(VO).
For example,
The problem is that I need to convert a country List to String Array, sort it and then put it in a list. However I am getting a ClassCastException.
String [] countriesArray = countryList.toArray(new String[countryList.size()]);
I have assumed that your country List name is countryList.
So to convert ArrayList of any class into array use following code. Convert T into the class whose arrays you want to create.
List<T> list = new ArrayList<T>();
T [] countries = list.toArray(new T[list.size()]);
Please help me to convert ArrayList to String[], ArrayList Contains
Values Object(VO) as Values.
As you mentioned that list contains Values Object i.e. your own class you need toString() overridden to make this work correctly.
This code works. Assuming VO is your Value Object class.
List<VO> listOfValueObject = new ArrayList<VO>();
listOfValueObject.add(new VO());
String[] result = new String[listOfValueObject.size()];
for (int i = 0; i < listOfValueObject.size(); i++) {
result[i] = listOfValueObject.get(i).toString();
}
Arrays.sort(result);
List<String> sortedList = Arrays.asList(result);
The snippet of
List<VO> listOfValueObject = new ArrayList<VO>();
listOfValueObject.add(new VO());
String[] countriesArray = listOfValueObject.toArray(new String[listOfValueObject.size()]);
will give you ArrayStoreException due VO is not the String type as required by native method arraycopy subsequently called from toArray one.
In case your ArrayList contains Strings, you can simply use the toArray method:
String[] array = list.toArray( new String[list.size()] );
If that is not the case (as your question is not completely clear on this), you will have to manually loop over all elements
List<MyRandomObject> list;
String[] array = new String[list.size() ];
for( int i = 0; i < list.size(); i++ ){
MyRandomObject listElement = list.get(i);
array[i] = convertObjectToString( listElement );
}
String[] array = list.toArray(new String[list.size()]);
What are we doing here:
String[] array is the String array you need to convert your
ArrayList to
list is your ArrayList of VO objects that you have in hand
List#toArray(String[] object) is the method to convert List objects
to Array objects
As correctly suggested by Viktor, I have edited my snippet.
The is a method in ArrayList(toArray) like:
List<VO> listOfValueObject // is your value object
String[] countries = new String[listOfValueObject.size()];
for (int i = 0; i < listOfValueObject.size(); i++) {
countries[i] = listOfValueObject.get(i).toString();
}
Then to sort you have::
Arrays.sort(countries);
Then re-converting to List like ::
List<String> countryList = Arrays.asList(countries);
Prior to Java 8 we have the option of iterating the list and populating the array, but with Java 8 we have the option of using stream as well. Check the following code:
//Populate few country objects where Country class stores name of country in field name.
List<Country> countries = new ArrayList<>();
countries.add(new Country("India"));
countries.add(new Country("USA"));
countries.add(new Country("Japan"));
// Iterate over list
String[] countryArray = new String[countries.size()];
int index = 0;
for (Country country : countries) {
countryArray[index] = country.getName();
index++;
}
// Java 8 has option of streams to get same size array
String[] stringArrayUsingStream = countries.stream().map(c->c.getName()).toArray(String[]::new);