Split ArrayList in multiple ArrayLists where values are same - java

Well im stuck on this point.
im trying to make sort function what does this.
parentarraylist = [1,1,1,2,3,2,3,3,2,2,1];
*magic*
childarraylist1 = [1,1,1,1];
childarraylist2 = [2,2,2,2];
childarraylist3 = [3,3,3];
the magic part is where im stuck.
i have tryied putting it in an for loop(the parent) and checking on the value. like this
int i = 0;
int finder = 0;
ArrayList<int> initArray = new ArrayList();
for(int list : parentarraylist){
if(i == 0){
finder = list
}
if(finder == list){
initArray.add(list);
parentarraylist.remove(list);
}else{
new ArrayList *value of list* = new ArrayList();
finder = list;
*value of list*.add(list);
}
}
this results in a view errors like
java.util.ConcurrentModificationException
and i cant set value of list
what can i do to make this work?

This little snippet should help you achieve your goal:
//maps will hold ALL unique integer as it's key
HashMap<Integer, ArrayList<Integer>> maps = new HashMap<Integer, ArrayList<Integer>>();
//your initial array, written inline for clarity
ArrayList<Integer> parentarraylist = new ArrayList<Integer>(Arrays.asList( new Integer[] {1,1,1,2,3,2,3,3,2,2,1}));
//get the iterator so that we won't need another temporary int variable for loop
Iterator<Integer> iterator = parentarraylist.iterator();
while(iterator.hasNext()){
//next = current integer in our array
Integer next = iterator.next();
//check if we have already have current integer or not
if(!maps.containsKey(next)){
//we don't have it, initialise an arraylist for this specific integer
ArrayList<Integer> x = new ArrayList<Integer>();
x.add(next);
//put it to our map holder
maps.put(next, x);
} else {
//already have it, add directly
maps.get(next).add(next);
}
}
This codes will print something like this:
printMap(maps);
//1 = [1, 1, 1, 1]
//2 = [2, 2, 2, 2]
//3 = [3, 3, 3]
printMap() is taken from this answer: Iterate through a HashMap
public static void printMap(Map mp) {
Iterator it = mp.entrySet().iterator();
while (it.hasNext()) {
Map.Entry pair = (Map.Entry)it.next();
System.out.println(pair.getKey() + " = " + pair.getValue());
it.remove(); // avoids a ConcurrentModificationException
}
}

You could try something like this:
public static void main(String[] args) {
ArrayList<Integer> parent = new ArrayList<Integer>();
ArrayList<ArrayList<Integer>> results = new ArrayList<ArrayList<Integer>>();
parent.add(3);
parent.add(1);
parent.add(1);
parent.add(2);
parent.add(3);
parent.add(3);
parent.add(1);
for(int i : parent)
{
boolean check = false;
for(ArrayList<Integer> result : results)
{
if(result.size() > 0)
{
if(result.get(0) == i)
{
check = true;
result.add(i);
break;
}
}
}
if(!check)
{
ArrayList<Integer> temp = new ArrayList<Integer>();
temp.add(i);
results.add(temp);
}
}
for(ArrayList<Integer> i : results)
{
for(int j : i)
{
System.out.print("" + j);
}
System.out.println();
}
}
Output:
333
111
2

The problem is that you remove an element from an array over which you are iterating. The
parentArrayList.remove(list);
causes the error here. If you remove this line your program will work. At the moment I do not see the benefit of removing the item from the parentArrayList for your sorting algorithm so just delete it and you are good to go.

Related

How can I left shift an array list by 2 post?

For example, there is an arraylist: 40 8 6 3 7 5 2, and I want to left shift them by 2 post. And then expected output is 6 3 7 5 2. I have wrote the following code, but it generate nothing
Code:
import java.util.ArrayList;
class ArrayLinearListRev extends ArrayLinearList{
public ArrayList<Integer> leftSh(int post, ArrayList<Integer>
alist2)
{
ArrayList<Integer> LeftshifedList = new ArrayList<Integer
();
for (int i = alist2.size(); i <= post; i++)
{
LeftshifedList.remove(alist2.get(i));
}
return LeftshifedList;
}
public void printElements(ArrayList<Integer> alist2)
{
for (int i = 0; i < alist2.size(); i++) {
System.out.print(alist2.get(i) + " ");
}
}
}
public class ArrayLinearListFun {
public static void main(String[] args)
{
ArrayLinearListRev obj = new ArrayLinearListRev();
ArrayList<Integer> x = new ArrayList<Integer>();
x.add(0, new Integer(2));
x.add(1, new Integer(5));
x.add(2, new Integer(7));
x.add(3, new Integer(3));
x.add(4, new Integer(6));
x.add(5, new Integer(8));
x.add(6, new Integer(40));
System.out.print("The list is: ");
obj.printElements(x);
x=obj.leftSh(2, x);
System.out.print("\nThe list is: ");
obj.printElements(x);
}
}
Your leftSh method returns an empty List. Assuming you don't want your method modify the original List, you should initialize LeftshifedList to be a copy of the original List.
You simply need to remove the element at index 0 and repeat post times.
public ArrayList<Integer> leftSh(int post, ArrayList<Integer> alist2)
{
ArrayList<Integer> LeftshifedList = new ArrayList<>(alist2); // create a copy of input List
for (int i = 1; i <= post; i++) { // remove the first post elements
LeftshifedList.remove(0);
}
return LeftshifedList;
}
Just remove first two elements.
public ArrayList<Integer> leftSh(int post, ArrayList<Integer> alist2) {
alist2.remove(0);
alist2.remove(0);
return alist2;
}

Copy Two Dimensional ArrayList as new

So the issue I'm having is after copying the 2d arraylist, changing the element from one 2d arraylist affects the other 2d arraylist. I want them to be completely separate in memory.
First example shows how it works correctly with 1d arraylists...
import java.util.ArrayList;
public class QuickTest {
public static void main(String[] args) {
ArrayList<Integer> firstList = new ArrayList<>();
ArrayList<Integer> secondList = new ArrayList<>();
Integer counter = 2;
for(int arrI = 0; arrI < 4; arrI++, counter+=2){
firstList.add(counter);
}
secondList = new ArrayList<>(firstList);
System.out.println("firstList.get(2) = " + firstList.get(2));
System.out.println("secondList.get(2) = " + secondList.get(2));
firstList.set(2, 7);
System.out.println("firstList.get(2) = " + firstList.get(2));
System.out.println("secondList.get(2) = " + secondList.get(2));
}
}
Expected output:
Notice how the element from the first arraylist is changed but not the second arraylist element is not changed. This is good and what we want.
Now to try and copy the 2d arraylists...
import java.util.ArrayList;
public class QuickTest {
public static void main(String[] args) {
ArrayList<ArrayList<Integer>> firstTwoDimList = new ArrayList<>();
ArrayList<ArrayList<Integer>> secondTwoDimList = new ArrayList<>();
firstTwoDimList.add(new ArrayList<Integer>());
firstTwoDimList.add(new ArrayList<Integer>());
firstTwoDimList.add(new ArrayList<Integer>());
Integer counter = 2;
for(int arrI = 0; arrI < firstTwoDimList.size(); arrI++, counter+=2){
firstTwoDimList.get(arrI).add(counter);
counter+=2;
firstTwoDimList.get(arrI).add(counter);
}
secondTwoDimList = new ArrayList<>(firstTwoDimList);
System.out.println("firstTwoDimList.get(1).get(0) = " + firstTwoDimList.get(1).get(0));
System.out.println("secondTwoDimList.get(1).get(0) = " + secondTwoDimList.get(1).get(0));
firstTwoDimList.get(1).set(0, 7);
System.out.println("firstTwoDimList.get(1).get(0) = " + firstTwoDimList.get(1).get(0));
System.out.println("secondTwoDimList.get(1).get(0) = " + secondTwoDimList.get(1).get(0));
}
}
Unexpected output:
Anyone have any idea what the reason for this is, and what the best solution would be?
This is what is happening in the 1D array list case, in terms of references:
This is what is happening in the 2D array list case:
This means that when you copy an array list using this:
new ArrayList<>(someOldArrayList)
the items themselves don't get copied, only a new array list object is created, referring to all the items in the old array list.
In the second case, you are only changing what array list 2's items are, but index 1 of first list and second list refers to the same array list 2.
To fix this, you need to copy the array lists inside first list and second list as well. One way to do this:
secondList = new ArrayList<>(firstList.stream().map(x -> new ArrayList<>(x)).collect(Collectors.toList()));
You should iterate through the size of the first dimension of the firstTwoDimArray and add new reference of each second dimension to the secondTwoDimArray. i.e.
for(int index = 0; index < firstTwoDimList.size(); index++) {
secondTwoDimList.add(new ArrayList<Integer>(firstTwoDimList.get(index)));
}
The difference between your first and second example is that in the second one you use get(). This get() returns a new variable, so you assign the integers to it and not to the original ArrayList.
If you want to assign a value:
firstTwoDimList.set(1, new ArrayList<Integer>(Arrays.asList(0, 7)));
I guess I was looking for something like this...
import java.util.ArrayList;
public class QuickTest {
public static ArrayList<ArrayList<Integer>> getTwoDimArrListCopy(ArrayList<ArrayList<Integer>> original){
ArrayList<ArrayList<Integer>> copy = new ArrayList<>();
for (ArrayList<Integer> arr: original){
copy.add(new ArrayList<Integer>(arr));
}
return copy;
}
public static void main(String[] args) {
ArrayList<ArrayList<Integer>> firstTwoDimList = new ArrayList<>();
ArrayList<ArrayList<Integer>> secondTwoDimList = new ArrayList<>();
firstTwoDimList.add(new ArrayList<Integer>());
firstTwoDimList.add(new ArrayList<Integer>());
firstTwoDimList.add(new ArrayList<Integer>());
Integer counter = 2;
for(int arrI = 0; arrI < firstTwoDimList.size(); arrI++, counter+=2){
firstTwoDimList.get(arrI).add(counter);
counter+=2;
firstTwoDimList.get(arrI).add(counter);
}
secondTwoDimList = getTwoDimArrListCopy(firstTwoDimList);
System.out.println("firstTwoDimList.get(1).get(0) = " + firstTwoDimList.get(1).get(0));
System.out.println("secondTwoDimList.get(1).get(0) = " + secondTwoDimList.get(1).get(0));
firstTwoDimList.get(1).set(0, 7);
System.out.println("firstTwoDimList.get(1).get(0) = " + firstTwoDimList.get(1).get(0));
System.out.println("secondTwoDimList.get(1).get(0) = " + secondTwoDimList.get(1).get(0));
}
}
I was just hoping there was a built in library that would do that getTwoDimArrListCopy() function for me...

Push An ArrayList of Strings Into HashMap

I am trying to split each element of an ArrayList into a char and double and push the results into a HashMap. So far, my code is this:
public static int TotalAmount(ArrayList<String> x) {
HashMap<Character,Double> hm = new HashMap<Character,Double>();
for(int i = 0; i < x.size(); i++) {
String[] s = x.get(i).split("(?<=\\d)(?=[a-zA-Z])");
hm.put(s[1].charAt(0), Double.parseDouble(s[0]));;
}
I do this with the ArrayList holding:
234K
1.3M
2.1M
211H
11K
But when I iterate through the HashMap, I get:
H, 211
K, 11
M, 2.1
I cannot seem to find where my logic went wrong. I might be able to accredit this to my intro to HashMaps. How do I ensure that I convert the ArrayList of Strings into a HashMap correctly?
To clear things up, I'm trying to completely move the ArrayList into a HashMap, without overwriting when the same key is found.
You can try this:
public static HashMap<Character, List<Double>> TotalAmount(ArrayList<String> initialList) {
HashMap<Character, List<Double>> resultMap = new HashMap<>();
for (String line : initialList) {
Double size = Double.parseDouble(line.substring(0, line.length() - 1));
Character sizeChar = line.charAt(line.length() - 1);
if (resultMap.containsKey(sizeChar)) {
resultMap.get(sizeChar).add(size);
} else {
resultMap.put(sizeChar, Collections.singletonList(size));
}
}
return resultMap;
}
Try this! I tested and it works fine! As QBrute mentioned, HashMap's put() overrides any value that is processed with the same key earlier.
I created method and the test(in main) using HashMap>
.
import java.util.*;
public class Question {
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<>();
list.add("234K");
list.add("1.3M");
list.add("2.1M");
list.add("221H");
list.add("11K");
HashMap<Character, ArrayList<Double>> result = TotalAmount(list);
System.out.println("K: " + result.get('K'));
System.out.println("M: " + result.get('M'));
System.out.println("H: " + result.get('H'));
}
public static HashMap<Character, ArrayList<Double>> TotalAmount(
ArrayList<String> x) {
HashMap<Character, ArrayList<Double>> map = new HashMap<>();
for (String line : x) {
Double num = Double.parseDouble(line.substring(0,
line.length() - 1));
Character c = line.charAt(line.length() - 1);
if (map.containsKey(c)) {
map.get(c).add(num);
} else {
ArrayList<Double> newList = new ArrayList<>();
newList.add(num);
map.put(c, newList);
}
}
return map;
}
}

Cannot count number in ArrayList using java

I am using the List as shown below:-
List<Integer> integerlist = new ArrayList<Integer>();
integerlist=primeFactors(numberToBERadical);
The primeFactors method return me some number when i sysOut as:-
System.out.println("integer list=="+integerlist);
integer list==[2, 2, 2, 3, 5]
My Problem is i want to count how many time that each number appears so that i can show Like this:-
2^3 * 3 * 5
You need to associate each factor with the number of times it occurs (the exponent).
To do that, a better data structure than a List would be a Map<Integer,Integer>.
Let's assume you still get a List from your primeFactors(numberToBERadical); (assuming you can't change it or don't want to for some reason).
You can do something like:
public static void main(String[] args) {
List<Integer> list = new ArrayList<>();
list.add(2);
list.add(2);
list.add(2);
list.add(3);
list.add(3);
list.add(5);
Map<Integer, Integer> factors = new HashMap<>();
for(Integer fact: list){
if(!factors.containsKey(fact)) { factors.put(fact, 1);}
else {
Integer value = factors.get(fact);
factors.put(fact, ++value);
}
}
System.out.println(factors);
}
Prints: {2=3, 3=2, 5=1}
If the array is sorted, you can count them like:
int count = 0;
int last = 0; // zero is not possible for prime-factors
for(int i=0;i<list.size();i++) {
if(i == 0 || last == list.get(i)) count++;
else {
if(last > list.get(0)) {
System.out.print(" * ");
}
System.out.print(last + (count > 1 ? "^" + count: ""));
count = 1;
}
last = list.get(i);
}
//print last sequence.
if(last > 0) {
if(last > list.get(0)) {
System.out.print(" * ");
}
System.out.print(last + (count > 1 ? "^" + count: ""));
}
You need to use a Map<Integer, Integer> which you can override the put method in in order to count the instances of each Integer.
final Map<Integer, Integer> myStringMap = new HashMap<>(){
#override
public String put(final Integer key, final Integer value) {
if(contains(key)) {
return put(key, get(key) + 1);
} else {
return put(key, 1);
}
}
};
You could even use a TreeMap to have the prime factors sorted by size. I answered a very similar question here. Simply loop over your List and dump it into the map
for(final Integer integer : myList) {
myCountingMap.put(integer, 1);
}
Even better would be to change your factorising method to return a Map to begin with.
List<Integer> inputList = new ArrayList<Integer>();
inputList.add(2);
inputList.add(2);
inputList.add(2);
inputList.add(3);
inputList.add(3);
inputList.add(4);
Map<Integer, Integer> resultMap = new HashMap<Integer, Integer>();
boolean flag = false;
for(int val : inputList)
{
if(resultMap.get(val) == null)
{
resultMap.put(val, 1);
}
else
{
resultMap.put(val, (resultMap.get(val).intValue())+1);
}
}
for(int key : resultMap.keySet())
{
if(resultMap.get(key) == 1)
{
if(!flag)
{
System.out.print(key);
flag = true;
}
else
{
System.out.print("*"+key);
}
}
else
{
if(!flag)
{
System.out.print(key+"^"+resultMap.get(key));
flag = true;
}
else
{
System.out.print("*"+key+"^"+resultMap.get(key));
}
}
}
System.out.println();
One possible, but not the simplest solution:
public Map<Integer, AtomicInteger> primeFactors(List<Integer integerList) {
final Map<Integer, AtomicInteger> count = new HashMap<Integer, AtomicInteger>();
for (final Integer number : integerlist) {
if (count.containsKey(number)) {
count.get(number).incrementAndGet();
} else {
count.put(number, new AtomicInteger(1));
}
}
return count;
}

Getting unique elements of List

all I have list containing Duplicate values I want somehow to get only Unique values from it and store it another list or set.So that I can perform some operation on it.
My code:
{
List<Integer[]> list1 = new ArrayList<Integer[]>();
list1.add(new Integer[] { 1,10 });
list1.add(new Integer[] { 1,10 });
list1.add(new Integer[] { 1,10 });
list1.add(new Integer[] { 2,10 });
list1.add(new Integer[] { 1,10 });
list1.add(new Integer[] { 3,10 });
for(int i=0;i<list1.size();i++)
{
System.out.println("I - 0 :"+list1.get(i)[0]+"\t I - 1 :"+list1.get(i)[1]+"\n");
}
Set<Integer[]> uniquelist = new HashSet<Integer[]>(list1);
for(Integer[] number: uniquelist){
System.out.println(number[0]+"\t"+number[1]);
}
}
I want the result {1,10;2,10;3,10} to be in separate list.When i googled I got to know for unique we should use set as in Set<Integer[]> uniquelist = new HashSet<Integer[]>(list1); But after doing this I dont know how to access each elements Thanks in advance
Output:
1 10
2 10
1 10
3 10
1 10
1 10
You won't get the result you want using the normal Set approach. As your List contains Integer[], and then won't be considered unique by default. All the array objects are distinct. So, your Set will contain the same elements as your list. However, you can define your Custom Comparator, and use it with a TreeSet constructor.
Another way of doing it can be, define a method contains(List<Integer[]> list, Integer[] value), which checks whether your list contains that array. Define a list named uniqueList. Now, iterate over your original list, and then for each value, call contains method passing uniqueList and that value, as parameters.
Here's how your contains method would look like: -
public static boolean contains(List<Integer[]> list, Integer[] value) {
for (Integer[] arr: list) {
// We can compare two arrays using `Arrays.equals` method.
if (Arrays.equals(arr, value)) {
return true;
}
}
return false;
}
So, you can see that, checking for containment is not the same as, how it would look for just Integer.
Now, from your main method, use this code: -
List<Integer[]> unique = new ArrayList<Integer[]>();
for (Integer[] arr: list1) {
// Use your method here, to test whether this value - `arr`
// is already in `unique` List or not. If not, then add it.
if (!contains(unique, arr)) {
unique.add(arr);
}
}
for (Integer[] arr: unique) {
System.out.println(arr);
}
I would rather use a Set implementation in this case. Use LinkedHashSet if you want your elements to be ordered.
You could declare a class IntegerPair to hold your pairs:
class IntegerPair {
private int key;
private int value;
public IntegerPair(int k, int v) {
key = k;
value = v;
}
public int getKey() {
return key;
}
public int getValue() {
return value;
}
public int hashCode() {
return key * value;
}
public boolean equals(Object o) {
if (!(o instanceof IntegerPair)) {
return false;
}
IntegerPair other = (IntegerPair) o;
return key == other.key && value == other.value;
}
}
Declare it this way:
Set<IntegerPair> set = new LinkedHashSet<IntegerPair>();
Instead of putting new Integer[] values, just do set.add(new IntegerPair(1, 10));
You can loop through your elements using the foreach approach:
for (IntegerPair value : set) {
System.out.println(value.getKey() + " = " + value.getValue());
}
You can access elements by Iterator or by using for each loop
for(Integer number: setOfNumbers){
System.out.println(number);
}
Put them into set using your custom comparator like following:
new TreeSet(list1, new Comparator<Integer[]>() {
public int compare(Integer[] one, Integer[] two) {
int n = one.length;
for (int i = 0; i < n; i++) {
int comp = one.compareTo(two);
if (comp != 0) {
return comp;
}
}
return 0;
}
});
Pay attention that I used TreeSet that can accept custom comparator. It is because you are dealing with arrays. If however you define your own class that holds 2 int values you can make it to implement equals() and hashCode() that allows using any Set implementation.
the Integer[] number in your for loop is an array. to get the values inside you have to use number[index] instruction. to do that you can either do a classic while or for loop using a variable as an index
for(int i=0;i<number.length;i++) {
...
}
or a foreach loop:
for(Integer num : number){
...
}
This may help you...
public static void main(String [] args){
Set<Integer []> set = new TreeSet<Integer []>(new Comparator<Integer[]>(){
public int compare(Integer[] o1, Integer[] o2) {
if(o1.length == o2.length){
for(int i = 0; i < o1.length; i++){
if(o1[i] != o2[i]){
return -1;
}
}
return 0;
}
return -1;
}
});
set.add(new Integer[]{1,2});
set.add(new Integer[]{1,2});
set.add(new Integer[]{1,2});
set.add(new Integer[]{1,3});
int j = 0;
for(Integer[] i: set){
System.out.println("\nElements: "+j);
j++;
for(Integer k : i){
System.out.print(k+" ");
}
}
}
You need to use Comparator to compare two elements of same. As we don't have comparator for Array, Set will use actual object to compare.. using comparator you will have to tell set that this two arrays are same and do not add other same array
Try Table collection in Google-guava.
Example :
Table<Integer, Integer, Integer[]> sampleTable = HashBasedTable.create();
sampleTable.put(1, 10, new Integer[] { 1,10 });
sampleTable.put(2, 10, new Integer[] { 2,10 });
sampleTable.put(1, 10, new Integer[] { 1,10 });
So it will overwrite the duplicate values. Finally you have only unique values.

Categories

Resources