I am trying to make a program in Java about the Tabulation method. For those unfamiliar, one of the steps in Tabulation method is to group binaries with the same number of 1's digits. So we put the group with the same number of 1's digit in a arraylist. So if we have five different groups (1st group containing no 1's digits, 2nd group containing one 1's digits, and so on), we store them in another arraylist. Thus an arraylist of an arraylist.
In the Tabulation method, we compare the elements from each group with the elements from the proceeding group. Each time we find a similar element from the next group (exactly one digit that differs), then we put them in a new list. This list is again grouped from the number of 1's digit. Thus, we have an arraylist of an arraylist of an arraylist.
What I have here is a part of my code:
allTables.add(new ArrayList<ArrayList<String>>().set(count, new ArrayList<String>().add(mintermBinaries[i])));
allTables is just an arraylist of an arraylist of an arraylist. The integer count determines the number of 1's digit a binary has and sets it in that index, and finally mintermBinaries[i], is the ith index of the array that contains all binaries in ascending order. The whole code is within a for loop.
The problem is it won't compile because according to Eclipse, the arguments are not applicable. I don't know why.
After thinking about this a lot, I'm not sure if a three dimensional array is even a good thing to do. Can anyone help? What is a better way to solve this?
new ArrayList<ArrayList<String>>().set(
count,
new ArrayList<String>().add(mintermBinaries[i]))
The second argument of set(), which is supposed to be an ArrayList<String> (since you're calling it on an ArrayList<ArrayList<String>>), is the expression
new ArrayList<String>().add(mintermBinaries[i])
The type of this expression is the type of the value returned by the method add(). And add() returns a boolean. And a boolean is not an ArrayList<String>.
Don't try to write all your code in a single line. Replace that with
List<ArrayList<String>> listOfLists = new ArrayList<ArrayList<String>>();
ArrayList<String> innerList = new ArrayList<String>();
innerList.add(mintermBinaries[i]);
listOfLists.set(count, innerList);
As returninig result of List#add() and List#set() are different from what you expect, to use such one-liners, you need additional helper methods:
// Appends an item to the end of the list.
// Instead of `boolean`, returns modified list itself
static <T> List<T> add(List<T> list, T item) {
list.add(item);
return list;
}
// Sets an item to arbitrary position in `List`, expanding if needed.
// Instead of replaced item, returns modified list itself
static <T> List<T> set(List<T> list, int index, T item) {
if (list.size() <= index) {
for (int i = list.size(); i <= index; i++)
list.add(null);
}
list.set(index, item);
return list;
}
then you can write your code in one line:
add(allTables, set(new ArrayList<List<String>>(), count, add(new ArrayList<String>(), mintermBinaries[i])));
Although this is not very elegant and may be even confusing in your particular case (I'd also prefer to call List.add() and .set() sequentially), such approach may happen more clean and efficient in some situations.
Related
I need to write a method as part of the array list class that accepts an element as a parameter
The method removes all instances of that element and then returns a new list with only that element
public List<E> removeSubList(E element) {
ArrayList<E> removedList = new ArrayList<E>();
while(array_list.contains(element)) {
removedList.add(array_list.remove(array_list.indexOf(element)));}
return removedList;
}
}
This is what I have so far... two things:
Would this work?
And 2. I keep getting cannot invoke (method) on array type Object[], which array_list is
Thanks!
First, your cannot invoke (method) on array type Object[] error means that your array_list variable is actually an array of Objects, as Joni answered.
The following code is a static method that takes an extra parameter of an ArrayList. This corresponds to your array_list variable.
public static <E> List<E> removeSublist( E elt, ArrayList<E> aList) {
// first, count the number of occurrences of the element
int numOccurrences = Collections.frequency(aList, elt);
// remove all occurrences of elt from your list
aList.removeIf( currentElt -> currentElt.equals(elt));
// return a list with numOccurrences duplicates of elt
return Collections.nCopies(numOccurrences, elt);
}
Your loop approach would work too but it's more efficient to remove all occurrences at once and then return a list with the corresponding number of duplicates of elt. If you're going to use the loop approach, you need to put the return statement outside the loop.
To make this method part of a custom subclass of ArrayList, simply change the signature back to what you had originally. But make sure array_list is actually of type ArrayList.
Note, that duplicates will only be good if equals() and == are the same for the E object.
I need to remove only one occurence of an integer in a ArrayList of integers. My code right now removes all integers with a specific value.
list.removeIf(s -> s.equals(data));
If I have for example:
ArrayList<Integer> i = new ArrayList<Integer>();
i.add(1);
i.add(1);
i.add(3);
i.add(5);
and I want to remove only the first 1 or the second 1. Not both.
Solution
Use the List#remove method. That is exactly what it was made for, from the documentation:
Removes the first occurrence of the specified element from this list, if it is present (optional operation). If this list does not contain the element, it is unchanged. [...]
boolean wasRemoved = list.remove(data);
Removing ints
However, you might have a minor issue here. Your data type is Integer and data is probably of type int. And there is already a method with the signature List#remove(int) (documentation) which will remove the element at the given index, not the element itself.
You can bypass this by explicitly boxing your data to an Integer, which is what you actually have stored in the list:
boolean wasRemoved = list.remove((Integer) data);
Or directly make the data variable of type Integer instead of int.
Just use remove method from the list.remove(new Integer(data)), by the implementation you can see that it removes the first element then exits:
for (int index = 0; index < size; index++)
if (o.equals(elementData[index])) {
fastRemove(index);
return true;
}
I've been having trouble with the next thing: I have an arraylist with numbers in it, and I want to reverse the numbers in the list, as in, if it had 1 2 3, replace the values in the arraylist with 3 2 1. To that end, I created a method called reordenar(); which puts the last number in the first arraylist in the first spot in the second arraylist. After this is done, I don't know how to make the first arraylist get its numbers replaced by the second. Here's the code I've written.
package firstPackage;
import java.util.*;
public class firstMain {
public static Object reordenar(List n){
List secondList = new ArrayList();
for (int i=0; i<n.size(); i++){
secondList.add(n.size()-i);
}
return n;
}
public static void main(String[] args) {
// TODO Auto-generated method stub
List firstList = new ArrayList();
firstList.add("1");
firstList.add("2");
firstList.add("3");
firstList.add("7");
firstList.add("5");
firstList.add("6");
firstList.add("9");
reordenar(firstList);
System.out.println(firstList);
}
}
that code just prints out the normal order, not the rearranged one. thanks a lot for the help.
You don't need 2 ArrayLists to make this work. Just iterate upto half the elements of your ArrayList and use a temporary variable to exchange places between the 1st and the last, the second and the second form the end etc.
Also it's not a good idea to use ArrayList without giving the specific type it will contain like:
List<String> firstList = new ArrayList<String>();
The former (without the specific type) implies Object for your ArrayList which usually is too wide to be useful.
i've been stuck for hours now and can't find a solution.
I want to compare two ArrayLists where i want to put each unique element from one of the list into another arrayList.
For example, if my one arrayList contain {0,1,2,3} and i want to compare it to {{1},{2},{3}} i want to recieve {2} in my 'unqiue' arraylist
please help me
AFTER EDIT
I will be more specific. ArrayList1={0,1,2,3,4} and ArrayList2={{0, 1} {0,1,2}} So what i want is to have the only unique from ArrayList1 in a single ArrayList. in this example i want ArrayList3= {3,4}
You can use method boolean removeAll(Collection c) of List.
It will removes all the elements that are contained in the specified collection from this list. So after invoking this your list will contain unique elements.
Suppose you have arrayList1 and arrayList2 the you can compare them like this:
arrayList1.removeAll(arrayList2);
Now arrayList1 contains only unique elements.
If I am interpreting your question correctly, you want to form a new list of common elements in 2 lists? If so, iterate through one of the list and check to see if the second list contains(Object) that element, if so add it to the third list. I cannot provide a code sample at this very moment but when I get to a computer I will be glad to edit this (if necessary).
Edit:
The code would probably look something like this:
private static <T> List<T> getUniqueList(final List<T> first, final List<T> second){
final List<T> unique = new ArrayList<T>();
for(final T element : first)
if(second.contains(element))
unique.add(element);
return unique;
}
Or if you are using Java 8:
private static <T> List<T> getUniqueList(final List<T> first, final List<T> second){
final List<T> unique = new ArrayList<>();
first.stream().filter(second::contains).forEach(unique::add);
return unique;
}
I have a nested list like below (but it has 1,000's of the holder lists within the one main list). Say I need to sort the main list listEmailData by the value for each of its holder lists on the holder.get(2) index. I can't seem to figure out how to do this any advice is appreciated.
ArrayList listEmailData;
ArrayList holder = new ArrayList();
listEmailData.add(3)
listEmailData.add(323)
listEmailData.add(2342)
listEmailData.add(holder)
EDIT: To clarify, I have a list where each list entry contains a sub-list, within this sub-list a specific index contains a value that is a ranking. I need to sort the main list based on this ranking value within each sub-list.
2ND EDIT: Thanks for the help on this, got it working but its seems that its putting larger numbers first and large numbers later, I was hoping to reverse this so it goes from largest to smallest as I am
You should implement Comparator<T> to compare lists, then call
Collections.sort(listEmailData, comparator);
Your comparator would have to compare any two "sublists" - e.g. by fetching a particular value. For example:
public class ListComparator implements Comparator<List<Integer>>
{
private final int indexToCompare;
public ListComparator(int indexToCompare)
{
this.indexToCompare = indexToCompare;
}
public int compare(List<Integer> first, List<Integer> second)
{
// TODO: null checking
Integer firstValue = first.get(indexToCompare);
Integer secondValue = second.get(indexToCompare);
return firstValue.compareTo(secondValue);
}
}
Note that this is using generics - hopefully your real code is too.