Android:What to use instead of cursor - java

In my application I use cursor to get information from SQLite data base like this:
Cursor contacts = dataBase.select("SELECT _idContact FROM Contacts");
if (contacts.getCount() > 0) {
if (IMLayout.getVisibility() == View.VISIBLE) {
int k = contacts.getCount();
for (int j = 0; j < k; j++) {
if (j == 0) {
contacts.moveToFirst();
} else {
contacts.moveToNext();
}
What I want is to optimize the "for" using Enhanced for loop. For that I have to use an array, or other, but not cursors because the cursors are not working for Enhanced for loop. How to convert the cursor into an arrayList?

The enhanced for-loop only works on collections, iterables and arrays, and Cursor is none of those things.
You'll just have to use the methods provided, as you currently do. Alternatively, you'll have to suck the contents of the cursor into a collection, but then you're just making more work for yourself.

You can greatly simplify this logic as follows:
Cursor contacts = dataBase.select("SELECT _idContact FROM Contacts");
while (contacts.moveToNext()) {
// do stuff with this database entry
}

Related

How to create a counter inside a for loop for Iterable in Java and get the value of the counter variable

Here's my current code snippet:
Iterable<HashMap<String, EntityProperty>> results =
cloudTable.execute(query, propertyResolver);
if (results == null) {
System.out.println("No files processed");
exit_code = "exit_code=1";
} else {
for (HashMap<String, EntityProperty> entity : results) {
// don't know how to start the loop here
}
}
I have a query for retrieving a list of certain files in Microsoft Azure. Now I just need to show the number of files processed result.
I know the concept of what I should be doing, create a counter within the for loop, and then after the Iterations in that loop, whatever the value of that counter variable, it should also give me the count of files right? I just don't know how to start :( I've been reading so much about Iterable in Java but still can't get a grasp on how it would work.
Any inputs would be greatly appreciated
Like this?
Iterable<HashMap<String, EntityProperty>> results =
cloudTable.execute(query, propertyResolver);
int counter;
if (results == null) {
System.out.println("No files processed");
exit_code = "exit_code=1";
} else {
counter = 0;
for (HashMap<String, EntityProperty> entity : results) {
// don't know how to start the loop here
counter++;
}
//int size = results.size();
}

How can I iterate through JComboBox and Validate items

i am trying to iterate through JComboBox items i.e its connected to Database, whenever I click it it fetches data from Database and updates it. But its adding duplicate values in such case. I am trying to validate it by iterating through each item once added to JComboBox, if the existing item is similar to item I am trying to add then it shall not add and jump to other statement.
However I am then getting Null pointer error, in order to avoid this error first time I added counter -1, but once items are added and want to update, it gives error.
My JComboBox code is given below:
comboBox.addMouseListener(
new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent ev) {
List<Guest> list = null;
list = database.readGuest();
int n = list.size();
if(n <= 0) {
JOptionPane.showMessageDialog(null, "No data found.");
}else {
for(int count = 0; count < n; count++) {
g = list.get(count);
String pass = g.getPassportNp();
//String s = (String) comboBox.getItemAt(count-1);
//for(int i = 0; i < n; ++i) {
if(comboBox.getItemCount() != 0) {
if(comboBox.getItemAt(count-1).equals(pass)) {
continue;
}else {
comboBox.addItem(pass);
}
}else {
comboBox.addItem(pass);
}
//}
}
}
}
});
any solution for this?
You are not iterating over the items in the combobox, but only comparing to the last item in it. Your basic design should be 2 nested for-loops, one for going over your database items and one for going over the combobox items to check if the current database item is already in there. (You may also use List.contains instead of an nested loop which is clearer and shorter).
Side note: registering a mouselistener on the combobox seems like a design smell for this type of work. Fetching items from a database is not something you want to do on the EDT, but rather in a background thread. Also, you don't know what happens first: opening/animating the combobox (done by Swing), or modifying its contents? It makes it hard to think about the control flow, yet another reason to take a different approach.
Here is the solution which I figured it out. I hope helps others.
I created a List, and then added all items to it then..
int size = pass.size();
if(comboBox.getItemCount() != 0) {
comboBox.removeAllItems();
for(int c = 0; c < size; ++c) {
comboBox.addItem(pass.get(c));
}
}else {
for(int c = 0; c < size; ++c) {
comboBox.addItem(pass.get(c));
}
}

How can I refactor a `for` loop?

Problem
I want to be able to split up a for loop into a method, then put the for the method in the for loop to make it easier to read. Below demonstrates this:
Example.java
for(int member = firstMember; member < arrayOfMembers.length; member++) {
[...] other code
}
Should be refactored to:
Solution Example:
private boolean eachMemberInList() {
return int member = firstMember; member < arrayOfMembers.length; member++);
}
public static void main(String[] args) {
for(eachMemberInList());
}
Is this possible?
No, you cannot return or otherwise manipulate a for loop as if it were an object in Java.
However, what you're attempting to do is unnecessary. You can use an array directly in an "enhanced" for loop, since Java 1.5.
for (int member : arrayOfMembers) { ... }
It is more concise than attempting to create a method to manipulate a for loop, and it is even more concise than the standard for loop you're attempting to replace.
What you're talking about is turning a for loop, into a while loop.
for (; true; )
is equivalent to
while (true)
So, you're solution could be viewed as
while (someFunctionIsTrue()) {}
Don't want to get into religious debates here, but generally, if you're iterating over an array of objects, you really do want to use a for lop. Not necessarily because it's any different than a while loop using your solution, but because it's idiomatic. When a developer (an experienced developer) sees a for loop, the fact that you chose a for loop tells them something. It says, hey, I'm iterating over the objects of a container. What a while loop says, is that there is some condition, and while that condition is true do something.
While loops and for loops are identically in capability. By using them idiomatically, you can communicate your code more concisely and clearly. For example:
int index = 0;
while (index < array.size) {
doSomethingWithArrayElement(array[index]);
index++;
}
This is not concise. The hanging variable declaration creates an extra line of code, as does the index++ at the end. When you do this:
for(int i = 0; i < array.size; i++) {
doSomething(array[i]);
}
This is very concise, and your use of a for loop... if used concistently like this, immediately tells a developer that all items of this container are going to have something done with them!
Now let's use the alternate example, where we have a function that returns a boolean. And this boolean tells the loop whether to continue or not. We could do something like this:
int index = 0;
for (; doSomethingWithArrayItem(array, index); index++){
}
boolean doSomethingWithArrayItem(array, index) {
//blah blah blah
if (index + 1 == array.size) return false;
return true;
}
This accomplishes what you want, but is difficult logic to follow. Let's say that you named your doSomething function something useful, like
incrementValueByTwo(item);
What do you think this function does? It's pretty clear right. Now, let's place this function in the for loop above:
int index = 0;
for (; incrementValueByTwo(array, index); index++){
}
How many values are we incrementing? Are we incrementing all the values of the array by 2? Some of them? The first one? Or perhaps none of them under certain circumstances? THIS IS VERY CONFUSING!!!! DON'T DO THIS!
I would rather do something like
String[] array = new String[10];
for(String variable : array){
doSomething(variable);
}
Or if you are using Java 8 then
Arrays.stream(array).forEach(memberOfArray -> doSomething(memberOfArray));
This is much more readable.

Insert into an already-sorted list

With Java, I have a class, known as TestClass, which has a member named Name, which is a string. I also have an ArrayList of this type, which is already sorted alphabetically by Name. What I want to do is find the best index in which to put a new instance of TestClass. The best approach I could come up with so far is this:
public static int findBestIndex(char entry, ArrayList<TestClass> list){
int desiredIndex = -1;
int oldPivot = list.size();
int pivot = list.size()/2;
do
{
char test = list.get(pivot).Name.charAt(0);
if (test == entry)
{
desiredIndex = pivot;
}
else if (Math.abs(oldPivot - pivot) <= 1)
{
if (test < entry)
{
desiredIndex = pivot + 1;
}
else
{
desiredIndex = pivot - 1;
}
}
else if (test < entry)
{
int tempPiv = pivot;
pivot = oldPivot - (oldPivot - pivot)/2;
oldPivot = tempPiv;
}
else
{
int tempPiv = pivot;
pivot = pivot - (oldPivot - pivot)/2;
oldPivot = tempPiv;
}
} while (desiredIndex < 0);
return desiredIndex;
}
Essentially, Break the array in half, check to see if your value goes before, after, or at that point. If it's after, check the first half of the array. Other wise, check the second half. Then, repeat. I understand that this method only tests by the first character, but that's easily fixed, and not relevant to my main problem. For some scenarios, this approach works well enough. For most, it works horribly. I assume that it isn't finding the new pivot point properly, and if that's the case, how would I fix it?
Edit: For clarification, I'm using this for an inventory system, so I'm not sure a LinkedList would be appropriate. I'm using an ArrayList because they are more familiar to me, and thus would be easier to translate into another language, if needed (which is likely, at the moment, might be moving over to C#). I'm trying to avoid things like Comparable for that reason, as I'd have to completely re-write if C# lacks it.
Edit part Duex: Figured out what I was doing wrong. Instead of using the previous pivot point, I should have been setting and changing the boundaries of the area I was checking, and creating the new pivot based on that.
It might not be a good idea to use a SortedSet (e.g. a TreeSet) for this, because Set‘s don't allow duplicate elements. If you have duplicate elements (i.e. TestClass instances with the same name), then a List should be used. To insert an element into an already sorted list is as simple as this:
void insert(List<TestClass> list, TestClass element) {
int index = Collections.binarySearch(list, element, Comparator.comparing(TestClass::getName));
if (index < 0) {
index = -index - 1;
}
list.add(index, element);
}
This code requires Java 8 or later, but can be rewritten to work in older Java versions as well.
As already pointed out, there is no reason to implement this by yourself, simple code example:
class FooBar implements Comparable<FooBar> {
String name;
#Override
public int compareTo(FooBar other) {
return name.compareTo(other.name);
}
}
TreeSet<FooBar> foobarSet = new TreeSet<>();
FooBar f1;
foobarSet.add(new FooBar("2"));
foobarSet.add(f1 = new FooBar("1"));
int index = foobarSet.headSet(f1).size();
(Based on How to find the index of an element in a TreeSet?)
I think the problem is in this bit of the code:
else if (test < entry)
{
int tempPiv = pivot;
pivot = oldPivot - (oldPivot - pivot)/2;
oldPivot = tempPiv;
}
else
{
int tempPiv = pivot;
pivot = pivot - (oldPivot - pivot)/2;
oldPivot = tempPiv;
}
You are peforming the same actions wether test < entry or wether test > entry. This will lead to a linear search when the item you are searching for is at the start of the array.
I prefer to use (low and high) like
high = list.size();
low = 0;
do {
pivot = (high + low) / 2;
if (test < entry) {
low = pivot;
} else if (test > entry) {
high = pivot
} else {
....
}
} while ...;
You should use something like a PriorityQueue that already has a sense of order. Inserting into a collection with a sense of order will automatically place the element in the correct place with minimal time(usually log(n) or less).
If you want to do arbitrary inserts without this, then I would suggest using a LinkedList that won't have to be resorted or completely copied over to insert a single item like the ArrayList you currently have. While finding the correct insert location for a LinkedList will take up to O(n) time, in practice it will still be faster than using a log(n) search for the correct location in an ArrayList, but then needing to copy or sort it afterwards.
Also the code for finding the insert location in a linked list is much simpler.
if (next != null && next.compareTo(insertElement) > 0){
// You have the right location
}
There are other data structures used could use instead of list like a tree, priority queue etc.
Make a list implementation of your own, and in your add method have these lines:
wrappedList.add(object);
Collections.sort(wrappedList);

Adding Element of an Object in an Array in an Array to a String Array

I have a method that is suppose to traverse 2 arrays of Ojbects, the first being Menu of size 50, which contains Recipes, which hold up to 10 elements called ingredients, which holds up to 3 elements each, but I am only looking for their names! I want to take the matching names of those Ingredient elements in the Recipes and add them to my String array and then return it, here is my code...
public class Recipe implements Cloneable
{
String Name;
final int INGREDIENT_ARRAY_MAX = 10;
Ingredient Ingredients[] = new Ingredient[INGREDIENT_ARRAY_MAX];
public class RecipeBook
{
final static int MENU_ARRAY_MAX = 50;
static Recipe Menu[] = new Recipe[MENU_ARRAY_MAX];
public static String[] getRecipesByIngredient(String ingredientName)
{
String[] targetRecipes = new String[MENU_ARRAY_MAX];
int counter = 0;
for (int j = 0; j < Menu.length; j++)
{
if (Menu[j] == null)
{
break;
}
else
{
for (int k = 0; k < Menu[j].Ingredients.length; k++)
{
System.out.println(Menu[j].Ingredients[k]);
if (Menu[j].Ingredients[k].getName().equals(ingredientName))
{
targetRecipes[counter] = Menu[j].getName();
counter++;
}
}
}
}
return targetRecipes;
}
}
}
Now I know it doesn't work and why, but the solution I am not sure about. At the moment I only have 3 Recipes and 3 Ingredients in each recipe! The stuff up top is just for reference, those are the object arrays of RecipeBook (Menu) and Recipes (Ingredients).
Now when ran this code gets me into a NullPointerException because tries testing nulls against Strings, but how could I make it check through the Recipe, if it doesn't find anything, it moves on to the next Recipe in Menu, if it does, it simply adds it but continues to check til finish. I tried adding "if" statements checking for nulls and not nulls but it becomes convoluted and it still doesn't get my program to return to checking the rest of the arrays. I know the first "if" can stay because, well if the spot i check in Menu is null, the rest of it must be null so there's no point in going farther. But how do I check the Ingredients array, find something, add it, and go back to sifting through the Menu for recipes with that ingredient? Is it possible to add an if inside the inner loop to check for null and if it is, just go back to the outer loop?
update if conditions as below
1st if condition :
if (Menu[j] == null || Menu[j].Ingredients == null || Menu[j].Ingredients.length ==0)
2nd if condition :
if (Menu[j].Ingredients[k] != null && ingredientName.equal(Menu[j].Ingredients[k].getName()))
please let me know if there any issues.
I don't know how you fill the recipe array but what i can say is that your code is missing a lot of null checks. I would go this way (code not compiled / tested):
public static String[] getRecipesByIngredient(String ingredientName) {
String[] targetRecipes = null;
// check input parameter ingredientName against null and do lookup only if it is not null
if(ingredientName != null) {
// init the result array and do look up
targetRecipes = new String[MENU_ARRAY_MAX];
for (int j = 0; j < Menu.length; j++) {
// you might run into NPE if Menu[j] or if the array of ingredients in Menu[j] (Menu[j].Ingredients) is null
if(Menu[j] != null && Menu[j].Ingredients != null) {
for (int k = 0; k < Menu[j].Ingredients.length; k++) {
// Menu[j].Ingredients[k] may also be null
// Menu[j].Ingredients[k].getName() may also be null but no need to check it since
// you call equals of the string object ingredientName witch you already checked
// and equals(null) is always false in that case
if (Menu[j].Ingredients[k] != null && ingredientName.equals(Menu[j].Ingredients[k].getName()) {
// here you might want to check Menu[j].getName() against null otherwise you'll have
// a null inside your result array (this is some like a land mine) unless you want
// to check against null while iterating over you result array
if(Menu[j].getName() != null) {
targetRecipes[counter++] = Menu[j].getName();
}
}
}
} // save the else...
}
} // else targetRecipes is still null, with witch you may want to say "no result found"
return targetRecipes;
}

Categories