I have the following list:
list 1= 1,2,3,4,5,6
I am trying to make a list that contains the following:
list c= 1,6,2,5,3,4
However, I cannot figure out how to do it. I know how to iterate through 6 but I don't know how to get to the last number and iterate backwards. I know a ListIterator can be used to go backwards but I still cannot figure it out.
This is what I did to add the original, I just don't understand how to iterate backwards:
public static void q(Set<String>list1)
{
Set<String>combined = new HashSet();
Iterator<String> forward = list1.iterator();
Iterator <String> backwards = list1.iterator();
for (int i=0; i<list1.size(); i++)
{
combined.add(forward.next());
//code to go backwards
}
}
This isn't to solve your problem, but rather to show you how ListIterator can be used to go backwards since you couldn't figure it out.
List<Integer> list = new ArrayList<>();
for (int n = 1; n <= 6; n++) { // Add 1, 2, ... 6 to list
list.add(n);
}
ListIterator it = list.listIterator(list.size());
while (it.hasPrevious()) {
System.out.println(it.previous());
}
The listIterator method of a List allows you to specify the index to start at as a parameter.
The hasPrevious method of the ListIterator checks if there is a previous element (self-explanitory).
The previous() method of the ListIterator returns the previous element in the list and moves the cursor position backwards.
Using ListIterator you can go forwards and backwards as you please using next() and previous() respectively.
Alternatively, using a for statement instead of using ListIterator...
for (int i = list.size() - 1; i >= 0; i--) {
System.out.println(list.get(i));
}
I am not sure if you really wanted a Set given you were talking about lists. This is the idea without explicitly using list iterators however they would behave the similarly.
How to use a list iterator: http://www.java2s.com/Tutorial/Java/0140__Collections/ListIteratorInreverseorder.htm
public static List<Integer> interleaveFrontBack(List<Integer> list) {
if (list.size() <= 2){
return new LinkedList<Integer>(list);
}
List interleaved = new LinkedList<Integer>();
int end = list.size() - 1;
int front = 0;
while (end > front){
interleaved.add(list.get(front++));
interleaved.add(list.get(end--));
}
// if odd sized list need to add last element
if (end == front){
interleaved.add(list.get(front));
}
return interleaved;
}
Simple Algo would be
1.) just use two positions , i =0 for increment and j = size-1 for decrements
2.) add elements to new list using i and j positions while traversing to the middle of the content list
Integer []aa=new Integer[]{1,2,3,4,5,6};
List<Integer> list =Arrays.asList(aa);
int n=list.size();
List<Integer> list2 =new ArrayList<>();
for (int i = 0,j=list.size()-1; i <n/2 ; i++,j--) {
list2.add(list.get(i));
list2.add(list.get(j));
}
// if(n%2!=0) list2.add(list.get(n/2)); // un-comment this , to handle
// odd list size too ,dynamism
list2.forEach(i->System.err.print(i+" "));
Output:
1 6 2 5 3 4
Assuming that you simply want to put the last element of the first list on the second index, you can do something like:
List<Integer> input = Arrays.asList(1, 2, 3, 4, 5, 6);
// create new list that initially contains first and last element of input list
List<Integer> output = new ArrayList<>(Arrays.asList(input.get(0), input.get(input.size()-1)));
// now iterate the "in between" input elements and add them to output
for (int i=1; i < input.size() -1 ; i++) {
output.add(input.get(i));
}
System.out.println("in: " + input);
System.out.println("out: " + output);
Of course, the above is just one way of doing this; there are many others
Not sure what your exactly looking for and where your code has broke. You could try:
List<Integer> intergers = new ArrayList<>();
for(int i = 1; i < 7; i++) {
if(i < 6) {
intergers.add((i-1), i);
} else {
intergers.add(1, i); //when i is 6 place it in the second index
}
}
System.out.println("List: " + intergers.toString());
With java list you can chose the index and if that index has a value the value well be pushed to the next index. It was the simplest thing I could think of. This is what it printed out:
List: [1, 6, 2, 3, 4, 5]
Related
So I have managed to implement reversing an ArrayList (of Strings) with the aid of a stack, but I cannot figure out how to do it with integers. I get a stack empty error, any ideas? [Java]
Here is the code:
package Class;
import java.util.ArrayList;
import java.util.Stack;
public class Class
{
static ArrayList<Integer> list = new ArrayList();
static Stack<Integer> stack = new Stack();
public static ArrayList<Integer> reverseList(ArrayList<Integer> n)
{
for(int i = 0; i < n.size(); i++)
{
stack.push(n.get(i));
n.remove(0);
}
for(int i = 0; i != stack.size();)
{
n.add(stack.pop());
}
return n;
}
public static void main(String[] args)
{
list.add(1);
list.add(2);
list.add(3);
list.add(4);
list.add(5);
System.out.println(list);
ArrayList n = reverseList(list);
System.out.println(n);
}
}
Error is empty stack error.
Instead of
for(int i = 0; i < n.size(); i++)
{
stack.push(n.get(i));
n.remove(0);
}
do this
for(int i = 0; i < n.size(); i++)
{
stack.push(n.get(i));
}
n.clear();
and it should work fine.
Without reinventing the wheel, can't you just use:
Collections.reverse(list);
When it comes to question, here:
for(int i = 0; i < n.size(); i++)
{
stack.push(n.get(i));
n.remove(0);
}
You are always removing the first element, but getting some in the middle afterwards, this leads to loosing some elements. You should use an Iterator for this. Check out the documentation for detailed description.
As already has been pointed out, one major problem is this part:
for(int i = 0; i < n.size(); i++)
{
stack.push(n.get(i));
n.remove(0);
}
Here you always remove the first element from the list but get the element at index i to add it to the stack.
Let's analyse that by taking your list of 1, 2, 3, 4, 5:
Step 1: i = 0 so you push 1 and remove 1 from the list which now becomes 2, 3, 4, 5
Step 2: i = 1 so you push 3 and remove 2, so the list now is 3, 4, 5
Step 3: i = 2 so you push 5 and remove 3. The list now is 4, 5 and has a length smaller than i so the loop stops.
The problem: you're not adjusting i to accomodate for the removal.
As m.k suggested you could add all elements to the stack and after that remove all.
Alternatively use an iterator:
for( Iterator<Integer> itr = n.iterator(); itr.hasNext(); ) {
stack.push(itr.next()); //this advances the iterator so only call next() once per iteration
itr.remove(); //this removes the element from the list
}
public static ArrayList<Integer> reverseList(ArrayList<Integer> n) {
for(int i = n.size()-1; i >=0; i--) {
stack.push(n.get(i));
}
n.clear();
while (stack.size() !=0)
n.add(stack.pop());
return n;
}
there's many ways to reverse things, but seems like it is important for you to use stack, so change your method a bit with above code
Here's my list:
myList =
["HEADING","POST","POST","POST","CALL_TO_ACTION","HEADING","POST","POST","POST","CALL_TO_ACTION","HEADING","POST","POST","CALL_TO_ACTION"]
I would like to have some logic in place that would help me divide myList into below three sub-lists (stored as, say, List<List<String> subLists):
["HEADING","POST","POST","POST","CALL_TO_ACTION"]
["HEADING","POST","POST","POST","CALL_TO_ACTION"]
["HEADING","POST","POST","CALL_TO_ACTION"]
Please note, the number three comes from the number of occurrences of the element "HEADING" (which I could find out using Collections.frequency(myList, "HEADING")).
One way to do this is,
Step 1: Collect all the indices from your myList where "HEADING" appears.
List<Integer> indexList = new ArrayList<>();
for(int index = 0; index < list.size(); index++) {
if(list.get(index).equals("HEADING"))
indexList.add(index);
}
Step 2: Iterate through this indexList and create sub lists by using current index and the next index.
for(int builderIndex = 0; builderIndex < indexList.size(); builderIndex++) {
List<String> test = null;
if(builderIndex == indexList.size() - 1) {
test = list.subList(indexList.get(builderIndex), list.size());
} else {
test = list.subList(indexList.get(builderIndex), indexList.get(builderIndex + 1));
}
System.out.println(test);
}
Boundary condition is to check if the current index is equal to one less than the size of the indexList. If yes, then the end index of the sub list would be the size of the original list.
I hope this helps.
This question already has answers here:
Iterating through a Collection, avoiding ConcurrentModificationException when removing objects in a loop
(31 answers)
Closed 6 years ago.
How do I reset a for-loop while looping through a list? For example, I want the for-loop to reset i.e. (i=0 and j=1) when there are duplicates in a list .
In this piece of code, I want the duplicates removed and the for-loop reset when subsequent entries in the list are equal. For instance, we have
list1 = [east, west, west, east]
I want the resultant list1 to be equal to an empty list.
This is because, When both "west" entries are eliminated, this results in the list updating to [east,east]. Since this is also a duplicate, the result must hence be an empty list [].
j=1;
for (int i=0;i<(list1.size()-1);i++){
if((list1.get(i)==list1.get(j))){
list1.remove(i);
list1.remove(i);
i=0;
j=1;
}else{
j++;
}
}
You can loop through the ArrayList reversely:
ArrayList<String> list1 = new ArrayList<String>(Arrays.asList(new String[]{"east", "west", "west", "east", "foo"}));
for (int i = (list1.size() - 2);i >= 0;i--){
for(int j = (list1.size() - 1);j > i;j--) {
if((list1.get(i).equals(list1.get(j)))) {
list1.remove(i);
list1.remove(i);
}
}
}
System.out.println(list1);
If you want the duplicates removed, why don't you use a Set ?
String[] list1 = {"east", "west", "west", "east"};
List<String> list = new ArrayList<>(Arrays.asList(list1));
Set<Object> alreadyPresent = new HashSet<>();
Iterator<String> iterator = list.iterator();
for (String element : new ArrayList<String>(list)) {
if (!alreadyPresent.add(element)) {
while(list.remove(element));
}
}
Edit (Much better) :
String[] list1 = {"a","b","b","a","d","e","f"};
List<String> list = new ArrayList<>(Arrays.asList(list1));
for (String element : new ArrayList<String>(list)) {
if(Collections.frequency(list, element) > 1) {
while(list.remove(element));
}
}
List<String> list1 = new ArrayList<String>();
list1.add("east");
list1.add("east");
list1.add("west");
list1.add("test");
list1.add("west");
int j=1;
for (int i=0;i<list1.size();i++){
//here you can say if you want exactly two or more
if(Collections.frequency(list1, list1.get(i)) > 1) {
list1.removeAll(Collections.singleton(list1.get(i)));
i=0;
}
}
System.out.println(list1);
Try modularizing your code a little bit more!
// The function you are trying to impliment
void removePairs(List<Object> list) {
while (removePair(list)) {}
}
Let's use a helper method to make our life easier
// Return true if successfully removed a pair
boolean removePair (List<Object> list) {
for(i = 0; i < list.size() - 1; i++) {
// Get the next objects
Object firstObject = list.get(i);
Object secondObject = list.get(i + 1);
if (firstObject.equals(secondObject)) {
list.remove(i);
list.remove(i + 1);
return true;
}
}
return false;
}
One other note, j = 1 should not be where it is. I am referring to variable scope. In your original code, you won't (hopefully) care about j after the for loop completes. But it is still hanging around, waiting to cause bugs when it gets used for something that it shouldn't!
To state the problem: if in the sequence to duplicate values appear [..., a, a, ...] you want to remove them, and recurse.
Most readable would be to do away with j or do int j = i - 1;.
List<String> list = new ArrayList<>();
Collections.addAll(list, "east", "west", "west", "east");
for (int i = 1; i < list.size(); ++i) {
String value = list.get(i);
int priorI = i - 1;
if (value.equals(list.get(priorI))) {
list.remove(priorI);
list.remove(priorI);
// next i will be priorI but at least 1
i = Math.max(0, priorI - 1); // With ++i will be > 0
}
}
I would like to write a function insertAndSort() that will take as parameter an Integer "num" and a List of integers "list". Let's assume the List lust is already sorted.
The algorithm is supposed to work this way :
Add "num" to L and keep the List sorted after "num" has been added.
Return the sorted List.
WARNING : We do not know whether the list is sorted ASC or DESC. And that is precisely my problem !
Example :
if "num" = 4 and L = {1, 3, 5, 7}, then the final sorted List is {1, 3, 4, 5, 7}
if "num" = 4 and L = {7, 5, 3, 1}, then the final sorted List is {7, 5, 4, 3, 1}
I can not use sorting API such as Collections.sort or Collections.reverseOrder etc...
So far, I've produced this code :
public static void main(String[] args) {
int num = 4;
List<Integer> myList = Arrays.asList(1, 3, 5, 7);
List<Integer> newList = new ArrayList<Integer>();
newList = insertAndSort(myList, num);
System.out.println(newList);
}
public static List<Integer> insertAndSort(List<Integer> list, int num) {
List<Integer> listSecond = new ArrayList<Integer>(list.size()+1);
for(int i = 0; i <= list.size() ; i++) {
if(num < list.get(i)) {
if(!listSecond.contains(num)){
listSecond.add(num);
} else {
listSecond.add(list.get(i-1));
listSecond.add(list.get(i));
break;
}
} else {
listSecond.add(list.get(i));
}
}
return listSecond;
}
The problem is that this seems to be working with a single type of List: the ascending one.
When I take a sorted descending List, it does not work anymore.
Do you have any idea to make this work with both type of List ?
Thanks and Regards.
First, you need to detect the sort order in the existing list.
If the list is empty, you don’t need to care, just add your element, you cannot break any existing sort order.
If the list contains one element, I cannot tell you what to do. Options include tossing a coin and throwing an exception, but there are more.
If the list contains two or more elements, iterate through them except for the last element, each time comparing the current element with the element in the next higher index. As soon as you encounter a pair of elements that are not equal, you know the sort order. If you only encounter equal elements, all the elements in the list are equal, and again I cannot tell you what to do.
Once you’ve detected a sort order, I suggest a big if-else statement to handle the two cases separately.
You already have the code for the ascending case. Except it doesn’t always work. If I try to insert 4 into { 1, 3, 5 }, I get an ArrayIndexOutOfBoundsException. If I try with { 1, 3, 5, 7, 9 }, the 9 is lost. You should probably find a fix for that.
You should be able to handle the descending case similarly to the ascending case. Only use num > list.get(i) instead of num < list.get(i).
First, you need to check whether the list is sorted in ASC or DESC. That's easy: compare the 1st two elements look for two consecutive non-identical elements and see whether the first one is greater or the second one (thanks tom for correcting the mistake).
Now, for a list sorted in ascending order, convert list to an ArrayList. Then, add num to the ArrayList and convert it to a TreeSet, since TreeSets sort their elements in ascending order. Finally, reassign the ArrayList to hold the contents of the TreeSet and return it.
For a list sorted in descending order, first, convert the TreeSet to an ArrayList, then iterate over this ArrayList in reverse order and add the elements to a new ArrayList. Return the second ArrayList.
public List<Integer> insertAndSort(List<Integer> list, int num){
ArrayList<Integer> a = new ArrayList<Integer>(list);
a.add(new Integer(num));
TreeSet t = new TreeSet(a);
a = new ArrayList<Integer>(t);
int l = list.size();
for(int i=1; i<l; i++){
if(list.get(i) != list.get(i-1))
break;
}
if(list.get(i) > list.get(i-1)) //ASC
return a;
else{ //DESC
ArrayList<Integer> a2 = new ArrayList<Integer>();
for(int i = a.size() - 1; i >= 0; i--)
a2.add(a.get(i));
return a2;
}
}
I would proceed with something like the code below. A few remarks :
it is possible to decide sort order if and only if there is at least 1 element AND first and last elements have different values.
the line int oo = list.get(p2) - list.get(p1); compute the
difference between the last and first element (negative = DESC,
positive = ASC)
the variable ox is positive if and only if the
added element is after the element pointed by the variable p3
whatever the order.
the position is found by a binary search algorithm by choosing p3 between p1 and p2 and deciding if the element is before or after p3.
This is not fully tested bu works with the examples you gave :
// static List<Integer> list = new ArrayList<>(Arrays.asList(7, 5, 3, 1));
static List<Integer> list = new ArrayList<>(Arrays.asList(1, 3, 5, 7));
static void add(int x)
{
// fixed code below (see Ole V.V. comment)
}
static public void main(String [ ] args)
{
add(4);
for(int x: list)
System.out.println(x);
}
EDIT: to be complete (see Ole V.V. comments)
When the new element is to be inserted before the first or after the last, two simple O(1) tests may be performed ; the general case has O(log N) complexity, this is more efficient than traversing the entire list which is O(N).
Be carefull too when comparing elements to deduce sort order, there may be several equal values ; the best is to compare the first and the last elements, this is O(1) - again better than O(N).
Algorithmic complexity is an important matter (to me) and was the primary aim of my post. The code of the add function becomes :
static void add(int x)
{
int p1 = 0;
int p2 = list.size() - 1;
if(list.size() == 0 || list.get(p1) == list.get(p2))
throw new IllegalStateException("Unable to decide sort order");
int oo = list.get(p2) - list.get(p1);
if(oo * (x - list.get(p1)) <= 0) // new element is before first
list.add(0, x);
else if(oo * (x - list.get(p2)) >= 0) // new element is after last
list.add(x);
else
{
while (p1 + 1 < p2)
{
int p3 = (p1 + p2) / 2;
int ox = (x - list.get(p3)) * oo;
if(ox >= 0) // new element is after p3
p1 = p3;
if(ox <= 0) // new element is before p3
p2 = p3;
}
list.add(p2, x);
}
}
Note : there may be still some undealed side effects. If the asker is interested, I am ready to give further help - just ask.
Your code and what you say is two different things.
Based on code you made, I see that List can't contain more than one instance of same value.
If thats the case, main method should look like this:
public static void main(String[] args){
int num = 4;
List<Integer> myList = Arrays.asList(1, 3, 4, 5, 7);
List<Integer> newList;
if (!myList.contains(num)) {
newList = insertAndSort(myList, num);
} else {
newList = copyList(myList);
}
System.out.println(newList);
}
if thats not the case:
public static void main(String[] args){
int num = 4;
List<Integer> myList = Arrays.asList(1, 3, 4, 5, 7);
List<Integer> newList;
newList = insertAndSort(myList, num);
System.out.println(newList);
}
Methods that main method use:
Assuming we can only know how list is sorted by values in list, we have to decide default sort method when there is only 1 value or all values are same. I picked ASC as default. If elements can be of same value and we are certain list is sorted its best to compare lowest value in list with the highest one. With this approach we have to compare 2 elements only once.
So method to see if list is sorted DESC would look like this:
private static boolean isDesc(List<Integer> list) {
return list.get(0) > list.get(list.size() - 1);
}
If method returns true its sorted DESC. With returning false its ASC. If we want to change default value, when values don't tell us how its sorted and we want it to be DESC we would replace '>' sign with '>='
private static boolean isDesc(List<Integer> list) {
return list.get(0) >= list.get(list.size() - 1);
}
Code for as you called it insertAndSort:
public static List<Integer> insertAndSort(List<Integer> list, int num) {
List<Integer> listSecond = new ArrayList<Integer>(list.size() + 1);
boolean isDescSortOrder = isDesc(list);
if (isDescSortOrder) {
int i = 0;
while ((i < list.size()) && (list.get(i) > num)) {
listSecond.add(list.get(i));
i++;
}
listSecond.add(num);
while (i < list.size()) {
listSecond.add(list.get(i));
i++;
}
} else { // is asc sort order
int i = 0;
while ((i < list.size()) && (list.get(i) < num)) {
listSecond.add(list.get(i));
i++;
}
listSecond.add(num);
while (i < list.size()) {
listSecond.add(list.get(i));
i++;
}
}
return listSecond;
}
Depending on how its sorted code got devided into 2 blocks. As we don't know on each iteration will be right place to insert our num value its better to use while loop. Using for loop and checking everytime if num value already exists in list is counterproductive. On top of that I dunno if your application should allow same values in the list. If I assume it should, you can't add num value if it already existed in the list with for loop and checking with contains every iteration.
And just to copy the table when list already has the element and we don't want to add elements that are already incuded:
public static List<Integer> copyList(List<Integer> list) {
List<Integer> listSecond = new ArrayList<Integer>(list.size());
for (int i = 0; i < list.size(); i++) {
listSecond.add(list.get(i));
}
return listSecond;
}
Also based on good programming practices I'd recommend to name methods based on what they do.
Calling method insertAndSort is asking for trouble. If I seen it, I'd say it alters list we are giving in parameter. Then it sorts it.
So putting unsorted list in it would give us unwanted outcome.
And I'd still ask myself why does it return a List when we are inserting an item to already existing list? I'd rather name it:
public static List<Integer> copySortedWithNewValue(List<Integer> sortedList, int newValue)
Try to use PriorityQueue. This collection contains a sorted sequence of elements which could be duplicated.
This question already has answers here:
Iterating through a Collection, avoiding ConcurrentModificationException when removing objects in a loop
(31 answers)
Closed 10 years ago.
I have array list of strings. I want to check in specific moment if in this array I have more elements than my "i", if yes I want to remove that elements. For example. I have five elements in array. I choose element which index is four. I want to check if exist higher element(in this case that higher will be element which index is 5) and remove that element. If I choose 3 element I want to remove 4 and 5 element. I do something like that:
for(int j = 0; j<descriptions.size();j++){
if(!descriptions.get(i+1).isEmpty()){
descriptions.remove(i+1);
}
}
This solution work good when I choose 3 element and two elements was removed. But when I want choose 4 element I get index out of bound exception. How I can solve my problem?
I don't quite see the point of using for loop in your code.
What you probably want to do is to remove any items beyond i th element in the list.
The easiest way to do is to repeatedly remove the last element from the list.
Here's a sample code for reference:
while(descriptions.size() > i){
descriptions.remove(descriptions.size()-1);
}
public static void main(String[] args) {
//list of string with 5 elements
List<String> descriptions = new ArrayList<String>();
descriptions.add("first");
descriptions.add("second");
descriptions.add("third");
descriptions.add("4");
descriptions.add("5");
//the size you want to check for the list
int i = 3;
int howMuchToRemove = descriptions.size()-i;
//if the list how more object from > i , we will remove objects from it
if (howMuchToRemove > 0)
for (int j=0 ; j < howMuchToRemove ; j++)
//remove the last object in the list
descriptions.remove(descriptions.size()-1);
System.out.println(descriptions.toString());
}
I have five elements in array. I choose element which index is four.
The fifth element is at index 4. if you want to choose the 4th element, it's index will be 3.
Modify your code as following:
int size = descriptions.size();
for(int j = size -1; j>choosenNum; j--)
{
descriptions.remove(j);
}
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<String>();
list.add("a");
list.add("a");
list.add("a");
list.add("a");
list.add("a");
indexToRemove(list, 5);
}
private static void indexToRemove(ArrayList<String> list, int index) {
if (list.size() > index) {
list.remove(index);
System.out.println(index + "th item removed");
} else
System.out.println("Can't remove");
}
You mean a function which will remove the given index element? then try this.
for(int i = descriptions.size()-1; i > indexToDeleteAfter; i--){
descriptions.remove(i);
}
Or, defer to ArrayList:
if(descriptions.size() - 1 > indexToDeleteAfter)
{
descriptions.removeRange(indexToDeleteAfter + 1, descriptions.size() - 1);
}
http://docs.oracle.com/javase/1.4.2/docs/api/java/util/ArrayList.html#removeRange(int,%20int)