Database ignoring rows with same value in column - Android - java

I am populating a RecyclerView with a table that has two columns it's basically a dictionary and when ever I call the method to start populating something unusual happens, the code ignores the rows with the same values in the first column "col1" and just get the last one and moves to the next and so on
JAVA
public void fetchData()
{
db =new DataBaseHelper(getContext());
try {
db.createDataBase();
db.openDataBase();
}
catch (Exception e)
{
e.printStackTrace();
}
namelist=new LinkedHashMap<>();
int ii;
SQLiteDatabase sd = db.getReadableDatabase();
Cursor cursor = sd.query("dictionary_lib" ,null, null, null, null, null, null);
ii=cursor.getColumnIndex("English_lib");
eng_list=new ArrayList<String>();
nor_list= new ArrayList<String>();
while (cursor.moveToNext()){
namelist.put(cursor.getString(ii), cursor.getString(cursor.getColumnIndex("German_lib")));
}
Iterator entries = namelist.entrySet().iterator();
while (entries.hasNext()) {
Map.Entry thisEntry = (Map.Entry) entries.next();
eng_list.add(String.valueOf(thisEntry.getKey()));
german_list.add(String.valueOf(thisEntry.getValue()));
}
for (int i = 0; i < eng_list.size(); i++) {
data.add(new DictObjectModel(eng_list.get(i), german_list.get(i)));
}
adapter = new CustomAdapter(data);
rv.setAdapter(adapter);
}
EXAMPLE OF THE DATABASE
here the recyclerview will ignore the first two rows of alpha and prints the third one and move to the next

This is actually most likely because you are putting the values in a LinkedHashMap which implements the map interface which states
An object that maps keys to values. A map cannot contain duplicate keys; each key can map to at most one value.
You are retrieving duplicate keys here:
while (cursor.moveToNext()){
namelist.put(cursor.getString(ii), cursor.getString(cursor.getColumnIndex("German_lib")));
}
So the first two example values are replaced in the map as the key "alpha" is duplicated.
To verify this you could just print out or step over the values within the loop above.
One way to resolve this would be to create your own java object:
public class Example
{
public String col1; // but appropriate names
public String col2;
// Add constructors or getters and setting if you want private members
}
then use an Arraylist and in your loop
List<Example> rows = new ArrayList<>;
while (cursor.moveToNext()){
Example e = new Example();
e.col1 = cursor.getString(ii);
e.col2 = cursor.getString(cursor.getColumnIndex("German_lib"))
rows.add(e)
}
EDIT
You are creating multiple loops just to get to the same result. So you could just within your cursor loop just put
data.add(new DictObjectModel(cursor.getString(ii), cursor.getString(cursor.getColumnIndex("German_lib")));

Related

Data structure like hashmap but with the ability to swap indexes in Java

I want to use a data structure to store column names of a JTable with their respective indexes, so that I can select the corresponding data column. If I filter out a column name, then the name and the index gets removed, if I put it back, the index will be the same. If I want to swap two columns, the indexes change but the column names stay the same. It also has to be serializable. Can I do this with a HashMap<String,Integer>?
I managed to load it with values, I basically filtered the dataList with the selected columnNames. I'm not too familiar with maps. As far as a know, I can't "swap" key's in HashMap
private List<Object[]> data = new ArrayList<Object[]>();
private List<String> columnNames = new ArrayList<String>();
public CustomTableModel(List<Object[]> dataList, Map<Integer,String> columnNames) {
for (Map.Entry<Integer, String> set : columnNames.entrySet()) {
this.columnNames.add(set.getValue());
}
ArrayList<Integer> selectedColIndexes = new ArrayList<Integer>();
for (Map.Entry<Integer, String> set : columnNames.entrySet()) {
selectedColIndexes.add(set.getKey());
}
for(int n=0; n<dataList.size(); n++) {
Object[] selectedRow = new Object[columnNames.size()];
for(int j=0; j<selectedColIndexes.size(); j++) {
int index = selectedColIndexes.get(j);
selectedRow[j]=dataList.get(n)[index];
}
data.add(selectedRow);
}
}

How to use a listAdapter to display Array of Json values

For an Android application that I'm building for my internship, I'm trying to display a list
of tickets from the current logged in user and display them in a ListView. Let me paste some of my code to let you see where I'm at currently:
JSONArray finalResult = finalResultObject.getJSONArray(TAG_TICKETS);
System.out.println("this is finalResult: " + finalResult);
// creating new HashMap
HashMap<String, String> map = new HashMap<String, String>();
// adding each child node to HashMap key => value
for (int i = 0; i < finalResult.length(); i++) {
JSONObject c = finalResult.getJSONObject(i);
if (c.has(TAG_CLIENT_NAME) && !c.isNull(TAG_CLIENT_NAME)) {
String clientName = c.getString(TAG_CLIENT_NAME);
map.put("client_name_map", clientName);
// System.out.println(clientName);
}
if (c.has(TAG_PROJECT_NAME) && !c.isNull(TAG_PROJECT_NAME)) {
String projectName = c.getString(TAG_PROJECT_NAME);
map.put("project_name_map", projectName);
}
// adding HashList to ArrayList
ticketList.add(map);
// System.out.println(map);
}
ListAdapter adapter = new SimpleAdapter(SecondActivity.this, ticketList, R.layout.list_item, new String[] { "client_name_map", "project_name_map" }, new int[] { R.id.client_name,
R.id.project_name });
eventualListAdapter = adapter;
I've got a couple of prints in between, left them in there to let you guys see what I'm looking at right now. My problem is that I do get the required number of items, but it repeats the same item (so it does loop through the array, but doesn't update the values). I'm currently completely new to Android, and therefore still figuring out which kind of Adapters to use etc.
In the end I'm passing the adapter to eventualListAdapter, which I created within the main thread, so I can easily call it to update the UI (I'm not sure if this is anywhere near a clean way, just trying to get things working at this point)
Thanks in advance,
Dennis
You are using the same HashMap instance for all Itens. Just move the HashMap creation to inside the loop:
// adding each child node to HashMap key => value
for (int i = 0; i < finalResult.length(); i++) {
// creating new HashMap
HashMap<String, String> map = new HashMap<String, String>();
JSONObject c = finalResult.getJSONObject(i);
if(c.has(TAG_CLIENT_NAME)&&!c.isNull(TAG_CLIENT_NAME)){
String clientName = c.getString(TAG_CLIENT_NAME);
map.put("client_name_map", clientName);
//System.out.println(clientName);
}
if(c.has(TAG_PROJECT_NAME)&&!c.isNull(TAG_PROJECT_NAME)){
String projectName = c.getString(TAG_PROJECT_NAME);
map.put("project_name_map", projectName);
}
// adding HashList to ArrayList
ticketList.add(map);
//System.out.println(map);
}

Adding values of repeated elements in ArrayList

I have an Arraylist of Records.
package com.demo.myproject;
public class Records
{
String countryName;
long numberOfDays;
public String getCountryName() {
return countryName;
}
public void setCountryName(String countryName) {
this.countryName = countryName;
}
public long getNumberOfDays() {
return numberOfDays;
}
public void setNumberOfDays(long numberOfDays) {
this.numberOfDays = numberOfDays;
}
Records(long days,String cName)
{
numberOfDays=days;
countryName=cName;
}
}
My Arraylist<Records> is containing the values
Singapore 12
Canada 3
United Sates 12
Singapore 21
I need to modify it such that my output is
Canada 3
Singapore 33
United States 12
Please help me with solution,approach.
You could store your Records in a Map, where the key would be the country.
When you receive a new Record, check if the country already is in the map, if it is, add the number of days, if not create it.
Map<String, Record> map = new HashMap<String, Record> ();
addRecord(map, someRecord);
private void addRecord(Map<String, Record> map, Record record) {
Record inMap = map.get(record.getCountryName());
if (inMap == null) {
inMap = record;
} else {
inMap.setNumberOfDays(inMap.getNumberOfDays() + record.getNumberOfDays());
}
map.put(record.getCountryName(), inMap);
}
Notes:
I have assumed that it is fine to modify the records - if not just create a new one using the sum of the days.
you can still get the collection of records by calling map.values(); and iterate over them
ArrayList is not very well suited for your use case. If you really need to stick to ArrayList, for evey new record, you would need to loop over the list, check if one of the records in the list has the same country as the new record, update that record if you find it, or add a new record if not.
public class RecordsMain {
static ArrayList<Records> al = new ArrayList<Records>();
static boolean flag = false;
public static void main(String[] args) {
Records rec1 = new Records(12,"Singapore");
Records rec2 = new Records(3,"Canada");
Records rec3 = new Records(12,"United States");
Records rec4 = new Records(21,"Singapore");
addToList(rec1);
addToList(rec2);
addToList(rec3);
addToList(rec4);
for (int i = 0; i < al.size(); i++) {
System.out.println(al.get(i).getCountryName() + " :: " + al.get(i).getNumberOfDays());
}
}
public static void addToList(Records records) {
for (int i = 0; i < al.size(); i++) {
if(al.get(i).getCountryName().equals(records.getCountryName())) {
al.get(i).setNumberOfDays(al.get(i).getNumberOfDays()+records.getNumberOfDays());
flag=true;
}
}
if (flag == false)
al.add(records);
}
}
Note:
The function addToList adds records and while adding itself checks whether the CountryNames are duplicate, if they are it adds the No of days and does not marks any new entry to the ArrayList.
I was not sure if you were looking for sorting of the List too, thus did not try that.
I suppose you create these records on your own. If you don't need any specific order of the elements you should use the HashMap and as assylias said - create country elements only when they doesn't exist. When you need to keep the order of elements (or sort them later by name etc) you can still use the ArrayList and "indexOf()" method to easily find them.
I dont know what exactly you want to do there but if you want to sort it with specific criteria then You could use comparable or comparator interfaces to sort your records using your criteria in ArrayList And use collections.sort() method to sort it.

How to build Arrays, push to them, and loop through them in Java/ Android

I come from an action script back ground and i am baffled by how to use arrays in java.
In my main activity i created an empty array called mIcons like so
private Array mIcons;
Now i want to set the value of that array by using a method from my DataBaseHelper class which looks like this:
public Array getHomeScreenIcons() {
Array iconList;
// Select All Query
String selectQuery = "SELECT * FROM " + homeIcons;
SQLiteDatabase db = this.getWritableDatabase();
Cursor cursor = db.rawQuery(selectQuery, null);
// looping through all rows and adding to list
if (cursor.moveToFirst()) {
do {
iconList.push(Integer.parseInt(cursor.getString(0)));
} while (cursor.moveToNext());
}
Log.v(TAG, "List Created");
// return contact list
}
that bold line jumping out of the code is the problem so far.. how do i PUSH to my array
Then later i will want to run a for loop for the array from my main activity using.length
Use an ArrayList paramaterized to any type you want
ArrayList<Integer> iconList = new ArrayList<Integer>();
add with
iconList.add(Integer.parseInt(cursor.getString(0)));
Iterate with
for (int i: iconList)
{
// i is your entire array starting at index 0
}
or
for (int i=0; i< iconList.size(), i++)
{
}
You're probably thinking about ArrayList
private ArrayList<String> iconList = ArrayList<String>();
iconList.add("Stuff");
and then later to loop through
for (int i=0; i<iconList.size(); i++) {
String newStuff = iconList.get(i);
}
You should probably hit up some basic java tutorials to get used to the array syntax and functionality. http://docs.oracle.com/javase/tutorial/java/nutsandbolts/arrays.html could be a good starting point.
Looking at your specific problem -
You generally don't want to use the Array class in the manner that you do. It's more of a helper class. Also, it seems that you are going for stack semantics, and you'd likely want to use a Stack instead.
First, arrays:
you declare an array like so:
Type[] myArray = new Type[arraySize];
and then you access it with index like so:
Type myThingFromArray = myArray[myArrayIndex];
and you put things in it like so:
myArray[myTargetIndex] = myObjectOfTypeType;
Raw arrays in java have static size and are not easily growable. For most applications it would be a better idea to use a member of the Collections framework instead. If you're actively looking for a stack (as you mention pushing) then you could use Stack<Integer> and have all the regular stack operations.
Another benefit of using a modern collection class is that you can iterate through your collection using the for-each construct, which eliminates some regular for boilerplate. An example:
public ArrayList<Integer> iconList;
public Array getHomeScreenIcons() {
Array iconList = new ArrayList<Integer>();
// Select All Query
String selectQuery = "SELECT * FROM " + homeIcons;
SQLiteDatabase db = this.getWritableDatabase();
Cursor cursor = db.rawQuery(selectQuery, null);
// looping through all rows and adding to list
if (cursor.moveToFirst()) {
do {
iconList.add(Integer.parseInt(cursor.getString(0)));
} while (cursor.moveToNext());
}
Log.v(TAG, "List Created");
// return contact list
//Iterate like so:
for (Integer i : iconList){
System.out.println("Here's all integers in the icon-list: " + i);
}
}
You can define arrays in Java like this:
int[] intArray = new int[3]; // array for three ints
String[] stringArray = new String[10]; // array for 10 Strings
So for your code, you can do something like this:
if (cursor.moveToFirst()) {
int[] iconList = new int[cursor.getCount()];
int index = 0;
do {
iconList[index] = Integer.parseInt(cursor.getString(0));
index++;
} while (cursor.moveToNext());
}
After that you can loop over the array like this:
for (int icon : iconList) {
// Do something with icon
}

java: converting DynaBean (apache-commons-beanutils) to List

I use apache-commons-beanutils DynaBean class in order to fetch rows from a database and to handle them outside of the mysql function.
is there a way to convert a DynaBean to a List without iterating through each row and manually creating the list ?
thanks!
so far I didn't get any answers so I wrote the function that iterates through the rows and creates an ArrayList of HashMap type (String, Object).
public ArrayList<HashMap<String,Object>> convertDynaBeanListToArrayList(List<DynaBean> theList) {
ArrayList<HashMap<String,Object>> result = new ArrayList<HashMap<String,Object>>();
DynaProperty[] dynaProperties = null;
for (Integer i=0;i<theList.size();i++) {
DynaBean row = theList.get(i);
HashMap<String,Object> resultRow=new HashMap<String,Object>();
// each raw got the same column names, no need to fetch this for every line
if (dynaProperties == null) {
dynaProperties = row.getDynaClass().getDynaProperties();
}
for (Integer j=0;j<dynaProperties.length;j++) {
String columnName=dynaProperties[j].getName();
resultRow.put(columnName, row.get(columnName));
}
result.add(resultRow);
}
return result;
}

Categories

Resources