Update specific item in arraylist - java

I want to update specific item in arraylist.
This is Conversation class:
class Conversation
{
String sender,to,name,bio,picture;
Integer id,time,unread;
public Conversation() {
}
public Conversation (int id,String sender,String to,String name,String bio,String picture,int time,int unread) {
this.sender=sender;
this.to=to;
this.id=id;
this.name=name;
this.bio=bio;
this.picture=picture;
this.time=time;
this.unread=unread;
}
public void setSender(String sender) {
this.sender=sender;
}
public void setTo(String to) {
this.to=to;
}
public void setId(int id) {
this.id=id;
}
public void setTime(int time) {
this.time=time;
}
public void setUnread(int unread) {
this.unread=unread;
}
public void setName(String name) {
this.name=name;
}
public void setBio(String bio) {
this.bio=bio;
}
public void setPicture(String picture) {
this.picture=picture;
}
public String getSender() {
return this.sender;
}
public String getTo() {
return this.to;
}
public int getId() {
return this.id;
}
public int getTime() {
return this.time;
}
public int getUnread() {
return this.unread;
}
public String getName() {
return this.name;
}
public String getBio() {
return this.bio;
}
public String getPicture() {
return this.picture;
}
}
I am adding items from database to this list with following lines:
public List<Conversation> getAllConversations() {
List<Conversation> conversationsList=new ArrayList<Conversation>();
String selectQuery = "SELECT * FROM " + TABLE_CONVERSATIONS+" order by id desc";
SQLiteDatabase db = this.getWritableDatabase();
Cursor cursor = db.rawQuery(selectQuery, null);
if (cursor.moveToFirst()) {
do {
Conversation Conversation = new Conversation();
Conversation.setId(Integer.parseInt(cursor.getString(0)));
Conversation.setSender(cursor.getString(1));
Conversation.setTo(cursor.getString(2));
Conversation.setName(cursor.getString(3));
Conversation.setBio(cursor.getString(4));
Conversation.setPicture(cursor.getString(5));
Conversation.setTime(Integer.parseInt(cursor.getString(6)));
Conversation.setUnread(Integer.parseInt(cursor.getString(7)));
conversationsList.add(Conversation);
} while (cursor.moveToNext());
}
return conversationsList;
}
I want to use setUnread method for specific item but how ? I know I can change like this:
conversationsList.get(location).setUnread(1);
But I don't know the location.I need to get the item with another parameter.e.g can I get the item by sender value ?
I need something like this:
conversationsList.getByUsername("username").setUnread(1);

An ArrayList can only be accessed by using a zero-based index. If you want to acces the elements by using another key (id or username) you need to use a Map or SparseArray (if you use a numeric key).
Since you wanted to lookup elements by "username", I'll use a map in the following example:
public Map<String, Conversation> getAllConversations() {
final Map<String, Conversation> conversations = new HashMap<>();
Cursor cursor = ...;
while (cursor.moveToNext()) {
Conversation conversation = new Conversation();
...
conversations.put(conversation.getSender(), conversation);
}
cursor.close(); // don't forget to close your cursors!
return conversations;
}
Then you can look up conversations like this:
conversations.get("John Doe").setUnread(1);
Note: You can use conversation.setTime(cursor.getInt(6)); instead of conversation.setTime(Integer.parseInt(cursor.getString(6)));. The SQLite database does not really care whether you store a string or an integer.

Related

Removing full object from a value

Helper Class
public class HomeScreenChatsHelper implements Comparable {
private String ID;
private String Name;
private String Image;
private String From;
private String Seen;
private String LastMessage;
private String LastMessageTime;
public HomeScreenChatsHelper(){
}
public HomeScreenChatsHelper(String id, String name, String image, String from, String seen, String lastmessage, String lastMessageTime) {
this.ID=id;
this.Name = name;
this.Image = image;
this.From = from;
this.Seen = seen;
this.LastMessage = lastmessage;
this.LastMessageTime = lastMessageTime;
}
public String getID() {
return ID;
}
public void setID(String id) {
ID = id;
}
public String getName() {
return Name;
}
public void setName(String name) {
Name = name;
}
public String getImage() {
return Image;
}
public void setImage(String image) {
Image = image;
}
public String getMessage() {
return LastMessage;
}
public void setMessage(String message) {
LastMessage = message;
}
public String getTime() {
return LastMessageTime;
}
public void setTime(String time) {
LastMessageTime = time;
}
public String getFrom() {
return From;
}
public void setFrom(String from) {
From = from;
}
public String getSeen() {
return Seen;
}
public void setSeen(String seen) {
Seen = seen;
}
#RequiresApi(api = Build.VERSION_CODES.KITKAT)
#Override
public int compareTo(Object comparestu) {
long compareage= Long.parseLong(((HomeScreenChatsHelper)comparestu).getTime());
long a = Long.parseLong(LastMessageTime);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
}
return Long.compare(a,compareage);
}
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof HomeScreenChatsHelper)) return false;
HomeScreenChatsHelper that = (HomeScreenChatsHelper) o;
return getID().equals(that.getID());
}
#Override
public int hashCode() {
return getID().hashCode();
}
Activity
for(HomeScreenChatsHelper str : mChats) {
if (str.getID().equals(ID)) {
mChats.remove(ID);
break;
}
}
There are a ton of tutorials on how to do it and I've spent the past week looking for a solution and I still don't have it. Is there anyway I can remove an whole object by just specifying just the ID? I wont have the values of all the other fields so I just want to remove a particular object by its ID. Also I cant use the clear option because I need the other data. So can someone help me out please?
With the present code nothing happens. No errors but doesn't work
By using java-8 you can filter the list, result will be the List<HomeScreenChatsHelper> that does have HomeScreenChatsHelper with same id
List<HomeScreenChatsHelper> mChats = new ArrayList<>();
//filter
List<HomeScreenChatsHelper> result = mChats.stream()
.filter(str->!str.getId().equals(Id)).
.collect(Collectors.toList());
Or by using Iterator
// Iterator.remove()
Iterator itr = mChats.iterator();
while (itr.hasNext())
{
HomeScreenChatsHelper x = itr.next();
if (x.getId().equals(Id)) }
itr.remove();
}
}
Your question is quite unclear. is mChats a List containing HomeScreenChatsHelper objects?
I assume so. If this is the case, then you can change your foreach loop into the normal loop
//Assuming mChats is List e.g ArrayList
for (int i = 0; mChats.size(); i++){
if (mChats.get(i).getID().equals(ID)) {
mChats.remove(i);
break;
}
}
The easiest way in Java 8 or later is with Collection#removeIf:
mChats.removeIf(str -> str.getID().equals(ID));
By the way, the convention in Java is for fields to begin with a lowercase letter.

How to get row from TableView?

I am creating a lobby application which will show all groups on a java tableview. Users are able to join groups that have space in them, else they will not be able to join.
I have been able to create this but I would like to be able to colour the row of the groups that have space in them in green and groups that are full will be coloured in red.
I will provide my code for this below. I am getting NullPointerException, which i dont know why. Thanks.
private void visualGroupAvailability() {
boolean isThereSpace;
for (currentGroupsModel o : groupsTable.getItems()) {
TableRow<currentGroupsModel> currentRow = getTableRow(o.getGroupID());
int limit = o.getNumberOfUsers();
isThereSpace = checkSpaceInGroup(o);
if(isThereSpace) {
currentRow.setStyle("-fx-background-color: #" + "388e3c ");
} else {
currentRow.setStyle("-fx-background-color: #" + "ffcdd2 ");
}
}
}
private TableRow<currentGroupsModel> getTableRow(int rowIndex) {
Set<Node> tableRowCell = groupsTable.lookupAll(".table-row-cell");
TableRow<currentGroupsModel> row = null;
for (Node tableRow : tableRowCell) {
TableRow<currentGroupsModel> r = (TableRow<currentGroupsModel>) tableRow;
row = r;
}
return row;
}
public class currentGroupsModel {
String groupName, groupDescription, hostName, groupType;
Integer numberOfUsers, groupID;
public currentGroupsModel(String gName, String gDesc, String hostName, String groupType, Integer numberOfUsers, Integer groupID){
this.groupName = gName;
this.groupDescription = gDesc;
this.hostName = hostName;
this.groupType = groupType;
this.numberOfUsers = numberOfUsers;
this.groupID = groupID;
}
public String getGroupName() {
return groupName;
}
public void setGroupName(String groupName) {
this.groupName = groupName;
}
public String getGroupDescription() {
return groupDescription;
}
public void setGroupDescription(String groupDescription) {
this.groupDescription = groupDescription;
}
public String getHostName() {
return hostName;
}
public void setHostName(String hostName) {
this.hostName = hostName;
}
public String getGroupType() {
return groupType;
}
public void setGroupType(String groupType) {
this.groupType = groupType;
}
public Integer getNumberOfUsers() {
return numberOfUsers;
}
public void setNumberOfUsers(int numberOfUsers) {
this.numberOfUsers = numberOfUsers;
}
public Integer getGroupID(){
return this.groupID;
}
public void setGroupID(Integer newID){
this.groupID = newID;
}
}
This question cannot really be answered with what you have given us. It is hard looking for a NullPointerException if there is a currentGroupModel we know nothing about and there are constant red hairings. For example why do you store something in limit, you never use it! Why do you pass getTableRow a rowIndex, that you are never using? As far as I get it your getTableRow returns the last TableRow in the table, not a specific one. Please consider fixing those problems first, before eventually providing some code to understand the inner workings of your currentGroupModel.

Room #Insert does not insert all records

I am running into an issue where only 1 record is being inserted into my Room SQLite DB.
When I perform a getAll(); the result only returns 1 record.
FOUND ISSUE: Genre[] genres = gson.fromJson(jsonArray.toString(), Genre[].class);
This line above is setting all "gid" values to 0, and I am not sure how to change that.
Genre.java
#Entity(indices = {#Index(value = {"id", "name"}, unique = true)})
public class Genre {
#PrimaryKey
private int gid;
//#ColumnInfo(name = "id") By Default - No need to annotate
#NonNull
private int id;
private String name;
public int getGid() {
return gid;
}
public void setGid(int gid) {
this.gid = gid;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
GenreDao.java
#Dao
public interface GenreDao {
#Query("SELECT * FROM Genre")
LiveData<List<Genre>> getAll();
#Insert(onConflict = OnConflictStrategy.REPLACE) //If there is a conflict, replace the record.
void insertAll(Genre... genres);
}
GenreRepository.java
public class GenreRepository {
private final GenreDao genreDao;
public GenreRepository(GenreDao genreDao) {
this.genreDao = genreDao;
}
//Database Methods
public void insertAll(Genre... genres) {
AsyncTask.execute(() -> { //Same as new Runnable()
genreDao.insertAll(genres);
});
}
public LiveData<List<Genre>> getAll() {
return genreDao.getAll();
}
}
APIUtil.java - getGenres() Method
This class makes an API call, returns the proper results, converts the JSONArray to a Genre[]. I can successfully loop through the Genre[] and confirm 10+ results come back.
public static void getGenres(Context context) {
APIWrapper wrapper = new APIWrapper(context, API_KEY);
Parameters params = new Parameters();
params.addFields(GENRE_FIELDS);
params.addLimit("50");
wrapper.genres(params, new onSuccessCallback() {
#Override
public void onSuccess(JSONArray jsonArray) {
Gson gson = new Gson();
Genre[] genres = gson.fromJson(jsonArray.toString(), Genre[].class);
//Insert DB
AppDatabase db = AppDatabase.getAppDatabase(context);
GenreRepository genreRepository = new GenreRepository(db.genreDao());
genreRepository.insertAll(genres);
}
#Override
public void onError(VolleyError volleyError) {
Log.e("GENRES ERROR:", volleyError.toString());
}
});
}
GenreViewModel.java
public class GenreViewModel extends ViewModel {
private GenreRepository genreRepository;
public GenreViewModel(GenreRepository genreRepository) {
this.genreRepository = genreRepository;
}
public void insertAll(Genre... genres){
genreRepository.insertAll(genres);
}
public LiveData<List<Genre>> getAll(){
return genreRepository.getAll();
}
}
SearchFragment.java
This is where I am retrieving the database values. This for loop only returns 1 result.
AppDatabase db = AppDatabase.getAppDatabase(getActivity());
GenreRepository genreRepository = new GenreRepository(db.genreDao());
GenreViewModel genreViewModel = new GenreViewModel(genreRepository);
genreViewModel.getAll().observe(this, genres -> { //new Observer<List<Genre>>()
for(Genre g : genres){
Log.e("GENRE", g.getName());
}
});
public void insertAll(Genre... genres){
genreRepository.insertAll(genres);
}
here is your mistake , what you provide as method definition and what you provide at call. see you make some thing wrong.
Solution
void insertAll(List<T> obj);
you can try with convert your array to list and put above in definition
I had this problem too.
And Solved it this way.
The problem was that the id that comes from server was mongoId and String so I should create a int primary key and pass currentTime as value to it so the database can insert all of them not replace them.
But you should consider using System.nanoTime() method instead of System.currentTimeMillis() cause sometimes it generates same value and then room replace them instead of inserting each one of them.

Saving arrayList to sqlite table using a model class

I am creating a database for which i am following the given procedure , but i need to insert bulk amount of data in differ differ columns ,for which do i have to add the values in Array and then should insert them to database ?? if yes then how ?? and by doing the same how i'll match/retrieve them with other table's data as i am having more tables.
Any kind of help/suggestions will truly appreciated.
Adding the value to table is like :
public void addMidSemQuestions(MidSemQuestions midSemQuestions)
{
openWritable();
m_sqLiteDatabase.beginTransaction();
try {
ContentValues values = new ContentValues();
values.put(KEY_SEM_ID, midSemQuestions.getId());
values.put(KEY_SUBJECT, midSemQuestions.getSubject());
values.put(KEY_QUESTION_ID, midSemQuestions.getQuestion_id());
values.put(KEY_QUESTION, midSemQuestions.getQuestion());
// Notice how we haven't specified the primary key. SQLite auto increments the primary key column.
m_sqLiteDatabase.insertOrThrow(MID_SEM_QUESTION_TABLE, null, values);
m_sqLiteDatabase.setTransactionSuccessful();
}catch (Exception e)
{
Log.d(LOG,"Error while trying to add mid sem questions to database");
}finally {
m_sqLiteDatabase.endTransaction();
}
}
and my model class is like :
public class MidSemQuestions
{
public int id;
public int sem_id;
public int sub_id;
public int marks_id;
public int question_id;
public String subject;
public String question;
public MidSemQuestions() {
}
public MidSemQuestions(int sem_id, int sub_id, int marks_id, int question_id, String subject,String question) {
this.sem_id = sem_id;
this.sub_id = sub_id;
this.marks_id = marks_id;
this.question_id = question_id;
this.subject=subject;
this.question = question;
}
public String getSubject() {
return subject;
}
public void setSubject(String subject) {
this.subject = subject;
}
public int getSub_id() {
return sub_id;
}
public void setSub_id(int sub_id) {
this.sub_id = sub_id;
}
public int getSem_id() {
return sem_id;
}
public void setSem_id(int sem_id) {
this.sem_id = sem_id;
}
public int getMarks_id() {
return marks_id;
}
public void setMarks_id(int marks_id) {
this.marks_id = marks_id;
}
public int getQuestion_id() {
return question_id;
}
public void setQuestion_id(int question_id) {
this.question_id = question_id;
}
public String getQuestion() {
return question;
}
public void setQuestion(String question) {
this.question = question;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
}
and i need to fill the data so for that i am doing like :
public void prepareDatabase()
{
final CDataSource cDataSource= new CDataSource(this);
if(cDataSource.getMidSemQuestionCount()==0)
{
//sem_id=1,sub_id=1,marks=2,
//que_id should be an array of 1 to 90,
//subject must be an array of strings,
//question also should be an array of strings
cDataSource.addMidSemQuestions(new MidSemQuestions(1,1,2,1,"C Programming","What are the data types?"));
//sem_id=1,sub_id=1,marks=5,que_id should be an array of 1 to 90,subject must be an array of strings,question also should be an array of strings
cDataSource.addMidSemQuestions(new MidSemQuestions(1,1,5,11,"C Programming","Difference b/w call by value?"));
//sem_id=1,sub_id=1,marks=10,que_id should be an array of 1 to 90,subject must be an array of strings,question also should be an array of strings
cDataSource.addMidSemQuestions(new MidSemQuestions(1,1,2,1,"C Programming","What are the data types?"));
}
}
suppose your have arraylist this fields,which contain all values, which
you want to insert in database using model class.
List<String> sem_id=new ArrayList<>();
List<String> String sub_id=new ArrayList<>();
List<String> String marks_id=new ArrayList<>();
List<String> String question_id=new ArrayList<>();
List<String> Strubg subject=new ArrayList<>();
List<String> String question=new ArrayList<>();
For saving into database,suppose, databasehelper.addData() is your database object to add data into database
for(int i=0;i<sem_id.size();i++{
databasehelper.addData(new CDataSource(this).addMidSemQuestions(
new MidSemQuestions(sub_id.get(i),
marks_id.get(i),question_id.get(i),
subject_id.get(i),question.get(i))));
}
and for fetching from Database bulk data, your database should return in
List format,
Here midsem list will get all values from Database
List<MidSemQuestions> midsem=new ArrayList<MidSemQuestions>();
midsem=database.getAllFieldsFromDatabase();
for(MidSemQuestions values:midsem){
String sub_id=values.getSub_id();
String sem_id=values.getSem_id();
String marks_id=values.getMarks_id();
String question_id=values.getQuestion_id();
String subject_id=values.getSubject_id();
String question=values.getQuestion();
//if you want array list then, put it in arraylist
//or anything you like
}

How i can design these with abstract class

When i want to add item to favorite .. i write this code my program and access everywhere: Favorite.add(itemid);
When i want to add item to message i write this code my program and access everywhere: Message.add(itemid);
Two class have some methods. So how i can design this useful?
For example;
AbstractData.addFavorite(itemid);
AbstractData.addMessage(itemid);
or
AbstractData<Fav>.add(itemid);
AbstractData<SMS>.add(itemid);
or
Your opinion?
Thank for help and sory for my little english...
Favorite.class
public class Favorite {
static SparseArray<Fav> LIST = new SparseArray<>();
public static boolean add(int ID){
if(!check(ID)){
LIST.put(ID, new Fav(ID, DateFormat.getDateTimeInstance().format(new Date())));
return true;
}
return false;
}
public static void remove(int ID){
if(LIST.indexOfKey(ID) >= 0 )
LIST.remove(ID);
}
public static boolean check(int ID){return LIST.get(ID) != null;}
public static Fav get(int ID){return LIST.get(ID);}
public static void saveALL(){
AsyncTask.execute(new Runnable() {
#Override
public void run() {
Fav favorite;
for (int i = 0; i < LISTE.size(); i++) {
favorite = get(LISTE.keyAt(i));
if (favorite != null)
//Saving data to xml
}
}
});
Log.d("DONE", "Favorite LIST Saving");
}
}
Fav.class
public class Fav implements IModel{
private int ID;
private String DATE;
public Fav(int ID, String DATE) {
this.ID = ID;
this.DATE = DATE;
}
public int getID() {
return ID;
}
public void setID(int ID) {
this.ID = ID;
}
public String getDate() {
return DATE;
}
public void setDate(String DATE) {
this.DATE = DATE;
}
}
Message.class
public class Message{
static SparseArray<SMS> LIST = new SparseArray<>();
public static boolean add(int ID){
if(!check(ID)){
LIST.put(ID, new SMS(ID, DateFormat.getDateTimeInstance().format(new Date())));
return true;
}
return false;
}
public static void remove(int ID){
if(LIST.indexOfKey(ID) >= 0 )
LIST.remove(ID);
}
public static boolean check(int ID){return LIST.get(ID) != null;}
public static SMS get(int ID){return LIST.get(ID);}
public static void saveALL(){
AsyncTask.execute(new Runnable() {
#Override
public void run() {
SMS message;
for (int i = 0; i < LISTE.size(); i++) {
message = get(LISTE.keyAt(i));
if (message != null)
//Saving data to xml
}
}
});
Log.d("DONE", "Message LIST Saving");
}
}
SMS.class
public class SMS implements IModel{
private int ID;
private String DATE;
public SMS(int ID, String DATE) {
this.ID = ID;
this.DATE = DATE;
}
public int getID() {
return ID;
}
public void setID(int ID) {
this.ID = ID;
}
public String getDate() {
return DATE;
}
public void setDate(String DATE) {
this.DATE = DATE;
}
}
IModel.class
public interface IModel {
int getID();
void setID(int ID);
String getDate();
void setDate(String DATE);
}
In my opinion...
Don't over-design your models.
Don't make your add and remove methods static, it will eventually leave you with headaches. You want your constructor to initialize your object.
Either use a Singleton Pattern to get a single instance of your manager object, or
Keep your manager class as a local variable in your Application class, make an access method for it, initialize it in onCreate().
Personally I've started to ditch the getter/setter pattern in favour of public fields, particularly if they're final like in enums. I know this is supposed to be ugly but... I don't care as long as it's convenient =)
So...
public class MyApplication extends Application
{
private static MyApplication instance;
private FavouritesManager favouritesManager;
public static getMyApplicationInstance ()
{
return instance;
}
public void onCreate ()
{
instance = this;
favouritesManager = new FavouritesManager(this); // You may want it to have a Context...
}
}
public class FavouritesManager
{
private Map<Integer,Favourites> favorites;
public FavouritesManager ()
{
load();
}
public void add ( Favourite favourite )
{
favourites.put(favourite.id, favourite);
}
public boolean contains ( int favouriteId )
{
favourites.contaisKey(favouriteId);
}
private void load ()
{
favourites = new HashMap<>();
// Maybe deserialize json from SharedPreferenecs?
}
public List<Favorite> getAll ()
{
// Return all Favourites, sorted by their SortOrder.
}
public Favorite create ( String name )
{
// Maybe a factory method that generates an unused id and returns a new Favourite instance?
}
}
public Favourite
{
public final int id;
public final Date createDate;
public String name;
public int sortOrder;
public Favorite ( int id, String name, int sortOrder )
{
this.id = id;
this.createDate = Date();
this.name = name;
this.sortOrder = sortOrder;
}
}
public class MyActivity extend Activity
{
protected void onCreate ( Bundle savedInstanceState )
{
FavouritesManager favmanager = MyApplication.getMyApplicationInstance().getFavoritesManager();
}
{
}
Make your classes Message and SMS implement the same interface IModel. Then, when you implement your methods (e.g. add()) and want them to accept both Message and SMS objects, use the base interface in your method signature:
public class AbstractData {
public static void add(final IModel data) { // <- Use interface here!
// ...
}
}
Now you can add objects this way:
Message msg = new Message();
AbstractData.add(msg);
SMS sms = new SMS();
AbstractData.add(sms);

Categories