I have a collection, and I want to implement the add() method, such that only positive integers can be added to the collection. The collection can hold 4 values, and I have used the code below to initialize every value as "-1".
public class Bag implements Collection {
private int[] elements;
public Bag() {
elements = new int[Runner.SIZE_OF_COLLECTION];
for (int i = 0; i < Runner.SIZE_OF_COLLECTION; i++) {
elements[i] = -1;
}
}
So far in the method add() below, I have this loop iterating through each element in the collection, and replacing each element that's less than 0 with the positive integer that I want to add ("toAdd").
The problem is, I only want to add the positive integer "toAdd" once, and without a break in the loop, the method replaces EVERY element "-1" in the collection with the positive integer. With the break in the loop, the method fails to add the positive integer at all. Any ideas on how I can get the method to add the positive integer to the collection only once?
public void add(int toAdd) {
for (int i = 0; i < Runner.SIZE_OF_COLLECTION; i++) {
if (elements[i] <= 0 && toAdd>0) {
elements[i] = toAdd;
}
break;
}
}
Thanks in advance!
Move the break into the if statement.
You could use an ArrayList instead of an int array. With an ArrayList, you could get the index of the first occurence of -1 and use the set method to add your new value at that index.
This replaces the first value from elements, which is equal or less than 0, with value from toAdd argument.
public void add(int toAdd) {
for (int i = 0; i < Runner.SIZE_OF_COLLECTION; i++) {
if (elements[i] <= 0 && toAdd>0) {
elements[i] = toAdd;
break;
}
}
}
The add method for the interface Collection takes an Object (or a generic type, which you have not specified). If you are trying to override / implement the collection interface method with your add method, then the method signature is incorrect, and it will never be called.
Your class needs to look like:
public class Bag implement Collection<Integer>
{
// ... other necessary methods
public boolean add(Integer i)
{
// your method...
}
}
And probably easier than your implementation would be to do:
public class Bag extends java.util.ArrayList<Integer>
{
#Override
public boolean add(Integer i)
{
if ((i != null) && (i > 0)) super.add(e);
}
}
You probably need to override the other add methods as well, although truthfully, it would be better to encapsulate the ArrayList instead of extending it.
Related
Is there an Iterator to loop over data structure in cycles?
Let's say there is an array:
int[] arr = {-1,5,7,-1,-1,-1}
I want to find index of first non -1 value from this array and starting to search from the random position (idx = random.nextInt(arr.length)). For example idx = 4;
So first check if arr[4] == -1, then if arr[5] == -1 and so on. If the end of the array reached then start from 0 position and continue until non -1 found. It is guaranteed that there will be at least one value not equal to -1 in the array.
This can be done so:
int idx = -1;
for (int i = random.nextInt(arr.length); ; i++) {
if (i == arr.length) {
/** start over */
i = 0;
}
if (-1 != arr[i]) {
idx = i;
break;
}
}
Or so:
int idx = -1;
int i = random.nextInt(arr.length);
do {
if (-1 != arr[i]) {
idx = i;
}
i == arr.length ? i=0 : i++;
} while (-1 == idx);
Is there an Iterator, that supports cycling (call next() , if the end of array reached then automatically start from 0)?
Limitations: 1) efficiency is not considered; 2) standard Java API is preferred.
in java API there is no such api which satisfy your problem but you can made it by your own.
what you can do is use List to create LinkedList. to solve your problem.
you can extend List to your class (CircularLinkedList extends List) & then override method hasNext() & getNext() thats all you need.
I don't think there are any iterators that let you know the index of the element as you call next(), so you'd have to keep track of the current index separately. You might be able to build up a "wrap-around" iterator using Guava's Iterators.concat (or some other third-party class) to concatenate an iterator over the trailing part of the array with an iterator over the leading part. However, I think the code is likely to be more complex than a simple for loop or two.
I believe there is no such circular Iterator that will automatically go to the beginning of the array once the end has been reached. I have created one below (not tested, and design is flawed), which requires an entirely new class of code, and is much longer than your short for/while loops.
public class MyCircularIterator<E> implements Iterator<E> {
private List<E> list;
private int pos;
public MyCircularIterator(List<E> list) {
this(list, 0);
}
public MyCircularIterator(List<E> list, int start) {
this.list = list;
pos = start;
}
public boolean hasNext() {
if(list.get(pos) != -1) return false;
return true;
}
public E next() {
if(hasNext()) {
E obj = list.get(pos);
pos = (pos + 1) % list.size();
return obj;
}
}
public void remove() {
list.remove(this.nextIndex);
}
}
Here is my code:
int setElement(int[]array) {
int key;
for (int i=0; i<array.length; i++) {
}
return key;
}
Something is wrong here.
As you said, your method needs to take three parameters, but your method takes just one input array. Also there is no need to loop through the array, array element can be accessed using its index for insertion, also for retrieval. Since the index is passed as parameter you can use it directly in your code.
All you need to do is
public void setValueInArray(int[] array, int index, int value){
if(array != null && index >= 0 && index < array.length){
array[index] = value;
}
}
key should be passed to the method.
The way you're doing it you'll never meet the if condition since key has a garbage value - It's only declared but never defined.
Try to pass the index and the value you are trying to change.
public void setElement(int[] array, int index, int val ) {
if(array!=null && index >-1 && index<array.length ){
array[index]=val ;
} else{
//sorry not possible
}
}
Integer myArray[]= {12,23,10,22,10};
System.out.println(Arrays.asList(myArray).indexOf(23));
use above code
I am trying to loop through 2 arrays, the outer array is longer then the other. It will loop through the first and if the 2nd array does not contain that int it will return a false. But I cannot figure out how to go about this. This is what I have so far:
public boolean linearIn(int[] outer, int[] inner) {
for (int i = 0; i < outer.length; i++) {
if (!inner.contains(outer[i])) {
return false;
}
}
return true;
}
I am getting this error when run:
Cannot invoke contains(int) on the array type int[]
I am wondering if it can be done without using a nested loop (like above). I know I'm doing something wrong and if anyone could help on the matter it would be great. Also I wasn't sure what class to look for in the java doc for the int[].
You could check that the larger of the arrays outer contains every element in the smaller one, i.e. inner:
public static boolean linearIn(Integer[] outer, Integer[] inner) {
return Arrays.asList(outer).containsAll(Arrays.asList(inner));
}
Note: Integer types are required for this approach to work. If primitives are used, then Arrays.asList will return a List containing a single element of type int[]. In that case, invoking containsAll will not check the actual content of the arrays but rather compare the primitive int array Object references.
You have two options using java.util.Arrays if you don't want to implement it yourself:
Arrays.toList(array).contains(x) which does exactly you are doing right now. It is the best thing to do if your array is not guaranteed to be sorted.
Arrays.binarySearch(x,array) provided if your array is sorted. It returns the index of the value you are search for, or a negative value. It will be much, much faster than regular looping.
If you would like to use contains then you need an ArrayList. See: http://docs.oracle.com/javase/7/docs/api/java/util/ArrayList.html#contains(java.lang.Object)
Otherwise, you need two loops.
There is a workaround like this:
public boolean linearIn(int[] outer, int[] inner) {
List<Integer> innerAsList = arrayToList(inner);
for (int i = 0; i < outer.length; i++) {
if (!innerAsList.contains(outer[i])) {
return false;
}
}
return true;
}
private List<Integer> arrayToList(int[] arr) {
List<Integer> result= new ArrayList<Integer>(arr.length);
for (int i : arr) {
result.add(i);
}
return result;
}
But don't think that looping is not happening, just because you don't see it. If you check the implementation of the ArrayList you would see that there is a for loop:
http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java/util/ArrayList.java#ArrayList.indexOf(java.lang.Object)
So you are not gaining any performance. You know your model best, and you might be able to write more optimized code.
The question above is a practice in my class. There is my friend' solution:
public boolean contains(int[] arrA, int[] arrB) {
if (arrB.length > arrA.length) return false;
if (arrB.length == 0 && arrA.length == 0) return false;
for (int count = 0, i = 0; i < arrA.length; i++) {
if (arrA[i] == arrB[count]) {
count++;
} else {
count = 0;
}
if (count == arrB.length) return true;
}
return false;
}
int[] is a primitive array. Meaning it does not have any special methods attached to it. You would have to manually write your own contains method that you can pass the array and the value to.
Alternatively you could use an array wrapper class such as ArrayList which does have a .contains method.
ArrayList<Integer> inner = new ArrayList<Integer>();
boolean containsOne = inner.contains(1);
contain method is reserved for ArrayList
Try this:
public boolean linearIn(int[] outer, int[] inner) {
for (int i = 0; i < outer.length; i++) {
for (int j = 0; j < inner.length; j++) {
if (outer[i] == inner[j])
return false;
}
}
return true;
}
I have written a SortedIntList class that has an add and get method.
I am calling the following four methods:
SortedIntList mySortedIntList = new SortedIntList();
mySortedIntList.add(9);
mySortedIntList.add(7);
System.out.println("0 is :"+mySortedIntList.get(0));
System.out.println("1 is :"+mySortedIntList.get(1));
My get and add methods looks like this:
public void add(Integer newValue) {
int position = 0;
while(position < list.size()){
int currentPosValue = list.get(position);
if(newValue <= currentPosValue){
for(int i=list.size()-1; i>=position; i--){
int toBeShifted = list.get(i);
list.set(i+1, toBeShifted);
}
list.set(position, newValue);
return;
}
position++;
}
list.add(newValue);
}
public int get(int i) throws IndexOutOfBoundsException {
// Postcondition: If i < 0 or i >= size() throws
// IndexOutOfBoundsException, otherwise returns the value
// at position i of this IntList
if (i < 0 || i >= list.size()) {
throw new IndexOutOfBoundsException("SortedIntList.get");
} else {
return ((Integer) list.get(i)).intValue();
}
}
public int get(int i) throws IndexOutOfBoundsException {
// Postcondition: If i < 0 or i >= size() throws
// IndexOutOfBoundsException, otherwise returns the value
// at position i of this IntList
if (i < 0 || i >= list.size()) {
throw new IndexOutOfBoundsException("SortedIntList.get");
} else {
return ((Integer) list.get(i)).intValue();
}
}
I have written it out on paper, and it seems logical, but the code blows up on:
System.out.println("1 is :"+mySortedIntList.get(1)) line, apparently 1 is outofbounds, but I don't see how.
Reading the Java Doc helps. Apparently using set() requires there to already be a value at the position you are trying to override. I needed to use add(position, value) instead :-)
It might be easier to use the Collections.sort(), this standard Java method will sort your Collection for you. This way you don't have to deal with the sorting yourself, good luck!
I see a couple of problems.
First, list.set(i+i, toBeShifted); should probably be list.set(i+1, toBeShifted);. When you are adding 7 to the list, your list size is 1. In the for loop, you initialize i to be 0 (list size - 1). When you call list.set(i+i, toBeShifted) you are calling list.set(0, toBeShifted), and so not actually shifting the value.
Second, though you don't run into it with adding a 9 and then a 7, you will end up in an infinite while loop. You never change the value of position. If you add a 9 and then a larger number, you're hosed.
You can't use list's set() to add to a list: for example, if you try to set something at index 1 to something in a list of size 1, you'll get an IndexOutOfBoundsException.
Basically, you need to add first.
Add a method void removeFirst(int newVal) to the IntegerList class that removes the first occurrence of a value from the list. If the value does not appear in the list, it should do nothing (but it's not an error). Removing an item should not change the size of the array, but note that the array values do need to remain contiguous, so when you remove a value you will have to shift everything after it down to fill up its space. Also remember to decrement the variable that keeps track of the number of elements.
Please help, I have tried all of the other solutions listed on this site regarding "removing an element from an array" and none have worked.
This method supports the same functionality as Collection.remove() which is how an ArrayList removes the first matching element.
public boolean remove(int n) {
for (int i = 0; i < size; i++) {
if (array[i] != n) continue;
size--;
System.arraycopy(array, i + 1, array, i, size - i);
return true;
}
return false;
}
Rather than write this code yourself, I suggest you look at Trove4J's TIntArrayList which is a wrapper for int[] You can also read the code for ArrayList to see how it is written.
You could do this:
int count; //No of elements in the array
for(i=0;i<count;i++)
{
if(Array[i]==element )
{
swap(Array,i,count);
if(count)
--count;
break;
}
}
int swap(int Array[],int i,int count)
{
int j;
for(j=i;j<=count-i;j++)
a[i]=a[i+1];
}
This is not the Full Implementation.You have to create a class and do this.
Using the method below
public static <TypeOfObject> TypeOfObject[] removeFirst(TypeOfObject[] array, TypeOfObject valueToRemove) {
TypeOfObject[] result = Arrays.copyOf(array, array.length - 1);
List<TypeOfObject> tempList = new ArrayList<>();
tempList.addAll(Arrays.asList(array));
tempList.remove(valueToRemove);
return tempList.toArray(result);
}
You can remove the first element of any array by calling the method as demonstrated in the below JUnit test.
#Test
public void removeFirstTest() {
// Given
Integer valToRemove = 5;
Integer[] input = {1,2,3,valToRemove,4,valToRemove,6,7,8,9};
Integer[] expected = {1,2,3,4,valToRemove,6,7,8,9};
// When
Integer[] actual = removeFirst(input, valToRemove);
// Then
Assert.assertArrayEquals(expected, actual);
}