How would I instantiate DictionaryADT dictionary in the constructor in this code? Also, If someone could help with the Iterators that would be cool. Lastly, if you could help with the print functions that would be nice.
import data_structures.*;
import java.util.Iterator;
public class ProductLookup {
DictionaryADT<String,StockItem> dictionary;
private int maxSize;
// Constructor. There is no argument-less constructor, or default size
public ProductLookup(int maxSize) {
this.maxSize = maxSize;
}
// Adds a new StockItem to the dictionary
public void addItem(String SKU, StockItem item) {
dictionary.insert(SKU,item);
}
// Returns the StockItem associated with the given SKU, if it is
// in the ProductLookup, null if it is not.
public StockItem getItem(String SKU) {
if (SKU == null)
return null;
return dictionary.getValue(SKU);
}
// Returns the retail price associated with the given SKU value.
// -.01 if the item is not in the dictionary
public float getRetail(String SKU) {
if (!dictionary.contains(SKU))
return (float) -.01;
return getItem(SKU).getRetail();
}
public float getCost(String SKU) {
if (!dictionary.contains(SKU))
return (float) -.01;
return getItem(SKU).getCost();
}
// Returns the description of the item, null if not in the dictionary.
public String getDescription(String SKU) {
if (!dictionary.contains(SKU))
return null;
return getItem(SKU).getDescription();
}
// Deletes the StockItem associated with the SKU if it is
// in the ProductLookup. Returns true if it was found and
// deleted, otherwise false.
public boolean deleteItem(String SKU) {
if (SKU == null)
return false;
return dictionary.remove(SKU);
}
// Prints a directory of all StockItems with their associated
// price, in sorted order (ordered by SKU).
public void printAll() {
Iterator<StockItem> iterator = values();
while (iterator.hasNext())
System.out.println(iterator.next().toString());
}
// Prints a directory of all StockItems from the given vendor,
// in sorted order (ordered by SKU).
public void print(String vendor) {
Iterator<StockItem> iterator = values();
if (dictionary.getItem(SKU).getVendor() == vendor)
System.out.println(tmp.toString());
}
// An iterator of the SKU keys.
public Iterator<String> keys() {
return new ;
}
// An iterator of the StockItem values.
public Iterator<StockItem> values() {
return null;
}
}
Why would it be any different than then way you have done maxSize?
public ProductLookup(int maxSize, DictionaryADT<String,StockItem> dictionary) {
this.dictionary = dictionary;
this(maxSize);
}
// Constructor. There is no argument-less constructor, or default size
public ProductLookup(int maxSize) {
this.maxSize = maxSize;
}
Related
I am trying to build an ArrayList that will contain objects. when i add an object to the list i want it to first check the array list for that object. and if it finds it i want it to increase a quantity variable in that object and not create a new object in the list. and then vice versa when removing objects. I have accomplished a way that works when removing an object. But i dont think i fully understand the methods in the arraylist or the logic when creating and arraylist of objects. as when i use .contains or .equals im not getting the desired effect.
public class ItemBag {
private ArrayList<Item> inventory = new ArrayList<Item>();
public ItemBag() {
}
public void addItem(Item objName, int quantity) {
if (inventory.contains(objName)) {
System.out.println("if statement is true!");
int i = inventory.indexOf(objName);
inventory.get(i).setQuantity(inventory.get(i).getQuantity() + quantity);
} else {
inventory.add(objName);
objName.setQuantity(quantity);
}
}
public void removeItems(String itemName, int quantiy) {
for (int i = 0; i < inventory.size(); i++) {
if (inventory.get(i).name() == itemName) {
inventory.get(i).setQuantity(inventory.get(i).getQuantity() - quantiy);
if (inventory.get(i).getQuantity() <= 0) {
inventory.remove(inventory.get(i));
}
}
}
}
public void showInventory() {
for (int i = 0; i < inventory.size(); i++) {
System.out.println(inventory.get(i).name() + " : " + inventory.get(i).getQuantity());
}
}
then when creating the itemBag in another object i am writing
ItemBag merchantItems = new ItemBag();
public void merchantBob() {
merchantItems.addItem(new HealthPotion() ,3);
merchantItems.showInventory();
System.out.println("add 1");
merchantItems.addItem(new HealthPotion(),1);
merchantItems.showInventory();
Items class
package Items;
public abstract class Item {
private int quantity = 0;
public Item() {
}
public abstract String name();
public abstract int cost();
public abstract String type();
public int getQuantity() {
return quantity;
}
public void setQuantity(int quantity) {
this.quantity = quantity;
}
}
HealthPotion Class
public class HealthPotion extends Potions {
protected int addHealth = 10;
#Override
public int drinkPotion() {
return addHealth;
}
#Override
public String name() {
return "Health Potion";
}
#Override
public int cost() {
return 5;
}
#Override
public String type() {
return "Potion";
}
}
The .contains() method would iterate through the list and use .equals() method to compare each element and check if the provided object exists in the list.
.equals() method would compare the object reference (unless .equals() is overridden) to check if the objects are same.
For reference: https://docs.oracle.com/javase/8/docs/api/java/util/Collection.html#contains-java.lang.Object-
You can override the .equals() method to compare the values of the provided object in the following way:
public abstract class Item {
private int quantity = 0;
public Item() {
}
public abstract String name();
public abstract int cost();
public abstract String type();
public int getQuantity() {
return quantity;
}
public void setQuantity(int quantity) {
this.quantity = quantity;
}
#Override
public boolean equals(Object object) {
if (this == object) return true;
if (object == null || getClass() != object.getClass()) return false;
Item providedItem = (Item) object;
return name == providedItem.name
&& cost == providedItem.cost
&& type == providedItem.type;
}
}
This should work
Hi guys I am making an inventory program and I am having trouble with the stockItem sorting method.which i need to use compareto to solve it.
This is my code so far. Please scroll to the bottom to see what I'm talking about.
public class Inventory {
private ArrayList<StockItem> stock;
public Inventory() {
stock = new ArrayList<StockItem>();
}
public void addStockItem(StockItem item) {
stock.add(item);
}
public int size() {
return stock.size();
}
public String toString() {
String result = "";
for(StockItem item: stock)
result+=item.toString()+"\n";
return result;
}
public boolean isValidIndex(int index) {
return index >=0 && index < stock.size();
}
/**
*
* #param index
* #return null if index is not valid, otherwise
* return item at that index
*/
public StockItem getItem(int index) {
if (index < 0 || index >= this.stock.size())// check if this index exists
return null; // removes the item the from stock and returns it
else
return this.stock.get(index);
}
/**
*
* #param index
* #return null if index is invalid, otherwise remove item at the given
* index and return the removed item.
*/
public StockItem remove(int index) {
if (index < 0 || index >= this.stock.size()) // check if this index exists
return null; // removes the item the from stock and returns it
else
return this.stock.remove(index);
}
/**
* sort, using {#link StockItem#compareTo(StockItem)}
* cannot use built-in sort method from java
*/
public void sort() {
}
I guess that you want to order your items by their sizes. You may use any existing algorithm for sorting such as selection sort, insertion sort or bubble sort. Furthermore, it is possible to use the Java built-in method from Collections module which is much faster and easier to implement. You may use Collections.sort() method given that your class is implementing Comparable interface and its abstract method compareTo(). You can implement comapreTo() method manually or just use Integer class to do so. I used the second approach. I am building a StockItem class with the necessary methods and fields you need to sort. Your code for Inventory should look like this:
import java.util.ArrayList;
import java.util.Collections;
public class Inventory {
private ArrayList<StockItem> stock;
public Inventory() {
stock = new ArrayList<StockItem>();
}
public void addStockItem(StockItem item) {
stock.add(item);
}
public int size() {
return stock.size();
}
public String toString() {
String result = "";
for(StockItem item: stock)
result+=item.toString()+"\n";
return result;
}
public boolean isValidIndex(int index) {
return index >=0 && index < stock.size();
}
/**
*
* #param index
* #return null if index is not valid, otherwise
* return item at that index
*/
public StockItem getItem(int index) {
if (index < 0 || index >= this.stock.size())// check if this index exists
return null; // removes the item the from stock and returns it
else
return this.stock.get(index);
}
/**
*
* #param index
* #return null if index is invalid, otherwise remove item at the given
* index and return the removed item.
*/
public StockItem remove(int index) {
if (index < 0 || index >= this.stock.size()) // check if this index exists
return null; // removes the item the from stock and returns it
else
return this.stock.remove(index);
}
/**
* sort, using {#link StockItem#compareTo(StockItem)}
* cannot use built-in sort method from java
*/
public void sort() {
Collections.sort(stock);
}
}
and your code for StockItem class should be similar to the following:
public class StockItem implements Comparable<StockItem>{
private int size;
public void setSize(int size) {
this.size = size;
}
public int getSize() {
return this.size;
}
public Integer getSizeNonPrimativeInt() {
return new Integer(this.getSize());
}
#Override
public int compareTo(StockItem item) {
return this.getSizeNonPrimativeInt().compareTo(item.getSizeNonPrimativeInt());
}
}
Hope this help ;)
You have not pasted your code for StockItem class. So I assume a sample class below and you can change your code accordingly. Lets assume your StockItem class like below:
class StockItem{
private String itemName;
private double itemPrice;
public String getItemName() {
return itemName;
}
public void setItemName(String itemName) {
this.itemName = itemName;
}
public double getItemPrice() {
return itemPrice;
}
public void setItemPrice(double itemPrice) {
this.itemPrice = itemPrice;
}
}
You mentioned you cannot use in-built sort() method from Collections, but I guess you might be pointed out you cannot use sort() method just because it sorts not the way you wanted? You need to define a comparator object with your custom sorting criteria and pass it to your in-built sort() method.
public class Inventory {
private ArrayList<StockItem> stock;
//-- your other code segments
static class ListComparator implements Comparator<StockItem>{
#Override
public int compare(StockItem o1, StockItem o2) {
if(o1.getItemName().compareTo(o2.getItemName())>0){
return 1;
}
else if(o1.getItemName().compareTo(o2.getItemName())<0){
return -1;
}
else
return 0;
}
}
public void sort() {
Collections.sort(stock, new ListComparator());
}
}
Is there any simple way to get the stack to display then empty itself inside the method "PrintAndEmpty"? I need the print and empty inside the method PrintAndEmpty and not the main. The codes are:
import java.util.*;
class Stack<E> implements StackInterface<E> {
private ArrayList<E> items;
public Stack() { // default constructor; creates an empty stack
items = new ArrayList<E>(); // initial capacity is 10
}
public Stack(int initialCapacity) {
//one argument constructor, creates a stack with initial capacity initialCapacity
items = new ArrayList<E>(initialCapacity);
}
public void push(E x) {
items.add(x); //uses the ArrayList method add(E o)
}
public E pop() {
if (empty()) // determine whether or not there is an item to remove
return null;
return items.remove(items.size()-1); //uses the ArrayList method remove(int n)
}
public boolean empty() {
return items.isEmpty();//uses the ArrayList method isEmpty()
}
public int size() {
return items.size(); //uses the ArayList method size()
}
public E peek() {
if (empty()) // determine whether or not there is an item on the stack
return null;
return items.get(items.size()-1); //uses the ArrayList method get(int i)
}
public void PrintAndEmpty()
{
// I want to print then empty the stack here, not in the main method.
}
Main method
public static void main (String[] args) // for demonstration only
{
Stack<Student> s = new Stack<Student>();
// push five Student references onto s
s.push(new Student("Spanky", "1245"));
s.push(new Student("Alfalfa", "1656"));
s.push(new Student("Darla", " 6525"));
s.push(new Student("Stimie", "1235"));
s.push(new Student("Jackie", "3498"));
// The data below is what I am trying to put in the PrintAndEmpty method
while(!s.empty())
System.out.println(s.pop().getName());
System.out.println();
System.out.println("The size of the stack is now "+s.size());
}
The Student Class for testing purposes:
public class Student
{
private String name;
private String id;
public Student()
{
name = "";
id = "";
}
public Student (String n, String idNum)
{
name = n;
id = idNum;
}
public String getName()
{
return name;
}
public String getID()
{
return id;
}
public void setName(String n)
{
name = n;
}
public void setID( String idNum)
{
id = idNum;
}
public boolean equals(Object o) // name and id are the same
{
return ( (((Student)o).name).equals(name) &&
(((Student)o).id).equals(id) );
}
}
I am all out of ideas as far as getting this to work. If anyone has suggestions, please let me know. I would greatly appreciate it!
Not sure why you'd want to do that, but here is how you would do it:
// PrintAndEmpty 'this' stack.
public void PrintAndEmpty()
{
// The condition to check - e.g. 'this' stack.
while(!this.empty()) {
// Pop from the stack - e.g. 'this' stack.
System.out.println(this.pop().getName());
}
}
I am creating a demo shopping cart in android for this i am using Application class for saving data. I am unable to delete data from linkedlist. I am calling removeItem() function for android activity for removing selected item from the list but it is not working any one can help me.
package in.co.santoshsharma.bookshopping;
import java.util.LinkedList;
import android.app.Application;
import android.content.res.Configuration;
public class GlobalData extends Application{
private String email;
private String itemName;
private int itemQuantity;
private int itemCost;
public GlobalData(){
}
public GlobalData(String iName,int iQunt,int iCost) {
// TODO Auto-generated constructor stub
this.itemCost=iCost;
this.itemName=iName;
this.itemQuantity=iQunt;
}
public void setEmail(String mail)
{
this.email=mail;
}
public String getEmail()
{
return email;
}
public String getItemName()
{
return itemName;
}
public int getItemCost()
{
return itemCost;
}
public int getItemQunt()
{
return itemQuantity;
}
LinkedList<GlobalData> list = new LinkedList<GlobalData>();
public void setList(String iName,int iQunt,int iCost)
{
list.add(new GlobalData( iName, iQunt, iCost));
}
public LinkedList<GlobalData> getList()
{
return list;
}
public void removeItem(String iName,int iQunt,int iCost)
{
for(GlobalData data:list)
{
if(data.getItemName().equals(iName))
{
list.remove(itemName);
//list.remove(iCost);
//list.remove(iQunt);
}
}
}
}
First, override equals() method and use itemName attribute for the comparison
#Override
public boolean equals(Object o) {
if (o == null) return false;
if (itemName == null) return false;
if (o instanceOf String) return itemName.equals(o);
else if (o instanceOf GlobalData) return ((GlobalData) o).itemName.equals(this.itemName);
else return false;
}
Then, change your removeItem() method
public void removeItem(String iName) {
list.remove(iName);
// or uncomment line below to completely remove all matching elements
// for (;;list.remove(iName)) {}
}
According to http://docs.oracle.com/javase/6/docs/api/java/util/LinkedList.html#remove(java.lang.Object) remove() method of a LinkedList will call the equals() method of the supplied Object and compare it with every element in the list.
Hope this helps :)
you cannot operate in lists (add, remove... items) while you iterate on them. You have to use an Iterator
for(Iterator<EmpDedup> iter = list.iterator(); iter.hasNext();) {
EmpDedup data = iter.next();
if (data.getRecord() == rec1) {
iter.remove();
}
}
see http://docs.oracle.com/javase/6/docs/api/java/util/Iterator.html
Refered from https://stackoverflow.com/a/10735435/1602230
Use a iterator to remove the element:
public void removeItem(String iName, int iQunt, int iCost) {
Iterator<GlobalData> iterator = list.iterator();
while (iterator.hasNext()) {
GlobalData data = iterator.next();
if (data.getItemName().equals(iName)) {
iterator.remove();
}
}
}
- You are Concurrently accessing and modifying the Collection, that can't be done from For-Each loop directly..
- Use Iterator to solve this problem.
LinkedList<GlobalData> q1 = new LinkedList<GlobalData>();
Iterator<GlobalData> iterator = q1.iterator();
while (iterator.hasNext()){
GlobalData mp = iterator.next();
if (mp.name.equals("xyz")){
iterator.remove(); // You can do the modification here.
}
}
You cannot modify a Collection using for-each loop. Use simple for loop or while.
The for-each loop hides the iterator, so you cannot call remove.
Therefore, the for-each loop is not usable for filtering. Similarly it
is not usable for loops where you need to replace elements in a list
or array as you traverse it.
Source: http://docs.oracle.com/javase/1.5.0/docs/guide/language/foreach.html
Generally, a collection named list storing elements of type E uses an iterator in the following way:
Iterator<E> iterator = list.iterator();
while(iterator.hasNext()) {
<do something with iterator.next()>;
}
Is there a way to iterate over Java SparseArray (for Android) ? I used sparsearray to easily get values by index. I could not find one.
Seems I found the solution. I hadn't properly noticed the keyAt(index) function.
So I'll go with something like this:
for(int i = 0; i < sparseArray.size(); i++) {
int key = sparseArray.keyAt(i);
// get the object by the key.
Object obj = sparseArray.get(key);
}
If you don't care about the keys, then valueAt(int) can be used to while iterating through the sparse array to access the values directly.
for(int i = 0, nsize = sparseArray.size(); i < nsize; i++) {
Object obj = sparseArray.valueAt(i);
}
Ooor you just create your own ListIterator:
public final class SparseArrayIterator<E> implements ListIterator<E> {
private final SparseArray<E> array;
private int cursor;
private boolean cursorNowhere;
/**
* #param array
* to iterate over.
* #return A ListIterator on the elements of the SparseArray. The elements
* are iterated in the same order as they occur in the SparseArray.
* {#link #nextIndex()} and {#link #previousIndex()} return a
* SparseArray key, not an index! To get the index, call
* {#link android.util.SparseArray#indexOfKey(int)}.
*/
public static <E> ListIterator<E> iterate(SparseArray<E> array) {
return iterateAt(array, -1);
}
/**
* #param array
* to iterate over.
* #param key
* to start the iteration at. {#link android.util.SparseArray#indexOfKey(int)}
* < 0 results in the same call as {#link #iterate(android.util.SparseArray)}.
* #return A ListIterator on the elements of the SparseArray. The elements
* are iterated in the same order as they occur in the SparseArray.
* {#link #nextIndex()} and {#link #previousIndex()} return a
* SparseArray key, not an index! To get the index, call
* {#link android.util.SparseArray#indexOfKey(int)}.
*/
public static <E> ListIterator<E> iterateAtKey(SparseArray<E> array, int key) {
return iterateAt(array, array.indexOfKey(key));
}
/**
* #param array
* to iterate over.
* #param location
* to start the iteration at. Value < 0 results in the same call
* as {#link #iterate(android.util.SparseArray)}. Value >
* {#link android.util.SparseArray#size()} set to that size.
* #return A ListIterator on the elements of the SparseArray. The elements
* are iterated in the same order as they occur in the SparseArray.
* {#link #nextIndex()} and {#link #previousIndex()} return a
* SparseArray key, not an index! To get the index, call
* {#link android.util.SparseArray#indexOfKey(int)}.
*/
public static <E> ListIterator<E> iterateAt(SparseArray<E> array, int location) {
return new SparseArrayIterator<E>(array, location);
}
private SparseArrayIterator(SparseArray<E> array, int location) {
this.array = array;
if (location < 0) {
cursor = -1;
cursorNowhere = true;
} else if (location < array.size()) {
cursor = location;
cursorNowhere = false;
} else {
cursor = array.size() - 1;
cursorNowhere = true;
}
}
#Override
public boolean hasNext() {
return cursor < array.size() - 1;
}
#Override
public boolean hasPrevious() {
return cursorNowhere && cursor >= 0 || cursor > 0;
}
#Override
public int nextIndex() {
if (hasNext()) {
return array.keyAt(cursor + 1);
} else {
throw new NoSuchElementException();
}
}
#Override
public int previousIndex() {
if (hasPrevious()) {
if (cursorNowhere) {
return array.keyAt(cursor);
} else {
return array.keyAt(cursor - 1);
}
} else {
throw new NoSuchElementException();
}
}
#Override
public E next() {
if (hasNext()) {
if (cursorNowhere) {
cursorNowhere = false;
}
cursor++;
return array.valueAt(cursor);
} else {
throw new NoSuchElementException();
}
}
#Override
public E previous() {
if (hasPrevious()) {
if (cursorNowhere) {
cursorNowhere = false;
} else {
cursor--;
}
return array.valueAt(cursor);
} else {
throw new NoSuchElementException();
}
}
#Override
public void add(E object) {
throw new UnsupportedOperationException();
}
#Override
public void remove() {
if (!cursorNowhere) {
array.remove(array.keyAt(cursor));
cursorNowhere = true;
cursor--;
} else {
throw new IllegalStateException();
}
}
#Override
public void set(E object) {
if (!cursorNowhere) {
array.setValueAt(cursor, object);
} else {
throw new IllegalStateException();
}
}
}
For whoever is using Kotlin, honestly the by far easiest way to iterate over a SparseArray is: Use the Kotlin extension from Anko or Android KTX! (credit to Yazazzello for pointing out Android KTX)
Simply call forEach { i, item -> }
Simple as Pie. Just make sure you fetch array size before actually performing the loop.
for(int i = 0, arraySize= mySparseArray.size(); i < arraySize; i++) {
Object obj = mySparseArray.get(/* int key = */ mySparseArray.keyAt(i));
}
Hope this helps.
For removing all the elements from SparseArray using the above looping leads to Exception.
To avoid this Follow the below code to remove all the elements from SparseArray using normal loops
private void getValues(){
for(int i=0; i<sparseArray.size(); i++){
int key = sparseArray.keyAt(i);
Log.d("Element at "+key, " is "+sparseArray.get(key));
sparseArray.remove(key);
i=-1;
}
}
Here is simple Iterator<T> and Iterable<T> implementations for SparseArray<T>:
public class SparseArrayIterator<T> implements Iterator<T> {
private final SparseArray<T> array;
private int index;
public SparseArrayIterator(SparseArray<T> array) {
this.array = array;
}
#Override
public boolean hasNext() {
return array.size() > index;
}
#Override
public T next() {
return array.valueAt(index++);
}
#Override
public void remove() {
array.removeAt(index);
}
}
public class SparseArrayIterable<T> implements Iterable<T> {
private final SparseArray<T> sparseArray;
public SparseArrayIterable(SparseArray<T> sparseArray) {
this.sparseArray = sparseArray;
}
#Override
public Iterator<T> iterator() {
return new SparseArrayIterator<>(sparseArray);
}
}
If you want to iterate not only a value but also a key:
public class SparseKeyValue<T> {
private final int key;
private final T value;
public SparseKeyValue(int key, T value) {
this.key = key;
this.value = value;
}
public int getKey() {
return key;
}
public T getValue() {
return value;
}
}
public class SparseArrayKeyValueIterator<T> implements Iterator<SparseKeyValue<T>> {
private final SparseArray<T> array;
private int index;
public SparseArrayKeyValueIterator(SparseArray<T> array) {
this.array = array;
}
#Override
public boolean hasNext() {
return array.size() > index;
}
#Override
public SparseKeyValue<T> next() {
SparseKeyValue<T> keyValue = new SparseKeyValue<>(array.keyAt(index), array.valueAt(index));
index++;
return keyValue;
}
#Override
public void remove() {
array.removeAt(index);
}
}
public class SparseArrayKeyValueIterable<T> implements Iterable<SparseKeyValue<T>> {
private final SparseArray<T> sparseArray;
public SparseArrayKeyValueIterable(SparseArray<T> sparseArray) {
this.sparseArray = sparseArray;
}
#Override
public Iterator<SparseKeyValue<T>> iterator() {
return new SparseArrayKeyValueIterator<T>(sparseArray);
}
}
It's useful to create utility methods that return Iterable<T> and Iterable<SparseKeyValue<T>>:
public abstract class SparseArrayUtils {
public static <T> Iterable<SparseKeyValue<T>> keyValueIterable(SparseArray<T> sparseArray) {
return new SparseArrayKeyValueIterable<>(sparseArray);
}
public static <T> Iterable<T> iterable(SparseArray<T> sparseArray) {
return new SparseArrayIterable<>(sparseArray);
}
}
Now you can iterate SparseArray<T>:
SparseArray<String> a = ...;
for (String s: SparseArrayUtils.iterable(a)) {
// ...
}
for (SparseKeyValue<String> s: SparseArrayUtils.keyValueIterable(a)) {
// ...
}
If you use Kotlin, you can use extension functions as such, for example:
fun <T> LongSparseArray<T>.valuesIterator(): Iterator<T> {
val nSize = this.size()
return object : Iterator<T> {
var i = 0
override fun hasNext(): Boolean = i < nSize
override fun next(): T = valueAt(i++)
}
}
fun <T> LongSparseArray<T>.keysIterator(): Iterator<Long> {
val nSize = this.size()
return object : Iterator<Long> {
var i = 0
override fun hasNext(): Boolean = i < nSize
override fun next(): Long = keyAt(i++)
}
}
fun <T> LongSparseArray<T>.entriesIterator(): Iterator<Pair<Long, T>> {
val nSize = this.size()
return object : Iterator<Pair<Long, T>> {
var i = 0
override fun hasNext(): Boolean = i < nSize
override fun next() = Pair(keyAt(i), valueAt(i++))
}
}
You can also convert to a list, if you wish. Example:
sparseArray.keysIterator().asSequence().toList()
I think it might even be safe to delete items using remove on the LongSparseArray itself (not on the iterator), as it is in ascending order.
EDIT: Seems there is even an easier way, by using collection-ktx (example here) . It's implemented in a very similar way to what I wrote, actally.
Gradle requires this:
implementation 'androidx.core:core-ktx:#'
implementation 'androidx.collection:collection-ktx:#'
Here's the usage for LongSparseArray :
val sparse= LongSparseArray<String>()
for (key in sparse.keyIterator()) {
}
for (value in sparse.valueIterator()) {
}
sparse.forEach { key, value ->
}
And for those that use Java, you can use LongSparseArrayKt.keyIterator , LongSparseArrayKt.valueIterator and LongSparseArrayKt.forEach , for example. Same for the other cases.
The answer is no because SparseArray doesn't provide it. As pst put it, this thing doesn't provide any interfaces.
You could loop from 0 - size() and skip values that return null, but that is about it.
As I state in my comment, if you need to iterate use a Map instead of a SparseArray. For example, use a TreeMap which iterates in order by the key.
TreeMap<Integer, MyType>
The accepted answer has some holes in it. The beauty of the SparseArray is that it allows gaps in the indeces. So, we could have two maps like so, in a SparseArray...
(0,true)
(250,true)
Notice the size here would be 2. If we iterate over size, we will only get values for the values mapped to index 0 and index 1. So the mapping with a key of 250 is not accessed.
for(int i = 0; i < sparseArray.size(); i++) {
int key = sparseArray.keyAt(i);
// get the object by the key.
Object obj = sparseArray.get(key);
}
The best way to do this is to iterate over the size of your data set, then check those indeces with a get() on the array. Here is an example with an adapter where I am allowing batch delete of items.
for (int index = 0; index < mAdapter.getItemCount(); index++) {
if (toDelete.get(index) == true) {
long idOfItemToDelete = (allItems.get(index).getId());
mDbManager.markItemForDeletion(idOfItemToDelete);
}
}
I think ideally the SparseArray family would have a getKeys() method, but alas it does not.