This is my recycler view in which I am storing my expense related information . I want to sum the amount paid of each corresponding user . For example , sadaf : Rs (50+10+5)=65 , Gulatiji: (50)Rs =50 , Amen :(50+5)= Rs 55 .
I thought of using hash map but the problem is that the user names in my recycler view are not unique . So , how should I store the sum of each corresponding user .
I have also tried this but this is giving me the wrong answer .
I am able to successfully sum the total amount column but for the amount paid , it is giving me the wrong answer. For the time being , I was just trying to calculate the total amount of a single user by using an integer variable my_total .I am getting the answer for sadaf as 110 but it should be 65.
calcuationAdap = new CalcuationAdap(Calculation.this,data);
for (int i = 0 ;i<data.size();i++) {
System.out.println(data.get(i).getItem());
main_total = main_total + Integer.parseInt(data.get(i).getTot_amt());
}
for(int i=0;i<data.size();i++)
{
for( int j=i+1;j<data.size()-1;j++)
{
if(data.get(i).getUser_name().equals(data.get(j).getUser_name()))
{
System.out.println(data.get(i).getUser_name());
my_total = my_total+Integer.parseInt(data.get(i).getMy_amt());
}
}
}
Toast.makeText(getApplicationContext(), String.valueOf(main_total ), Toast.LENGTH_SHORT).show();
Toast.makeText(getApplicationContext(), String.valueOf(my_total), Toast.LENGTH_SHORT).show();
If you have user id then use user id. other wise use below code to get each total amount
calcuationAdap = new CalcuationAdap(Calculation.this,data);
HashMap<String,Integer> result =new HashMap<>();
for (int i = 0 ;i<data.size();i++) {
System.out.println(data.get(i).getItem());
main_total = main_total + Integer.parseInt(data.get(i).getTot_amt());
}
for(int i=0;i<data.size();i++) {
if (result.containsKey(data.get(i).getUser_name())){
Integer addTotal=result.get(data.get(i).getUser_name());
addTotal= addTotal + Integer.parseInt(data.get(i).getMy_amt());
result.put(data.get(i).getUser_name(),addTotal);
}else {
result.put(data.get(i).getUser_name(),Integer.parseInt(data.get(i).getMy_amt()));
}
}
Toast.makeText(getApplicationContext(), String.valueOf(main_total ), Toast.LENGTH_SHORT).show();
for (Map.Entry<String, Integer> entry:result.entrySet()) {
System.out.println(entry.getKey() + "/" + entry.getValue());
Toast.makeText(getApplicationContext(), entry.getKey() + "/" + entry.getValue(), Toast.LENGTH_SHORT).show();
}
create a model class like
public class MyDataClass {
String userName;
String date;
String item;
int totoalAmount;
int amountPaid;
public int getAmountPaid() {
return amountPaid;
}
public int getTotoalAmount() {
return totoalAmount;
}
public String getDate() {
return date;
}
public String getItem() {
return item;
}
public String getUserName() {
return userName;
}
public void setAmountPaid(int amountPaid) {
this.amountPaid = amountPaid;
}
public void setDate(String date) {
this.date = date;
}
public void setItem(String item) {
this.item = item;
}
public void setTotoalAmount(int totoalAmount) {
this.totoalAmount = totoalAmount;
}
public void setUserName(String userName) {
this.userName = userName;
}
}
and whenever you need to store data as a list of such type create array list of this type like
ArrayList list =new ArrayList<>()
and create object of this class to store data with getter methods like
MyDataClass data =new MyDataClass()
data.setUserName("userName")
....
list.add(data);
and whenever you need to get data use getter method to get data like
list.get(index).getUserName();
Related
Here is my main issue, after some researches, I didn't find a solution so... I would like to sort my list of custom objects. These items have a price, but for a reason they are strings not int. I would like to know how to achieve this, thanks for helping !
Little personnal question, sorting a listview and a recyclerview are they done the same way ?
EDIT:
public class Product implements Parcelable {
private String imgUrl, titre, description, prix, nomAgence, pays, ville, type_produit, nbPieces = null;
List<String> urlImageList_thumb = new ArrayList<>();
List<String> urlImageList_full = new ArrayList<>();
private int isAdded = 0;
/* getters and setters*/
}
EDIT 2 :After your help, here's my code for comparable
#Override
public int compareTo(Product otherProduct) {
String tmp = prix.replace(" €", "");
String tmp2 = otherProduct.prix.replace(" €", "");
//Integer p1 = Integer.valueOf(tmp); --> does not work
//Integer p2 = Integer.valueOf(tmp2); --> does not work
Integer p1 = Integer.parseInt(tmp); //same error
Integer p2 = Integer.parseInt(tmp2); // same error
return p1.compareTo(p2);
}
Here's the code in the activity:
bouton_tri.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Collections.sort(productList);
}
});
EDIT 3 :
#Override
public int compareTo(Product otherProduct) {
String tmp = prix.replace(" €", "").replaceAll(" ", "");
String tmp2 = otherProduct.prix.replace(" €", "").replaceAll(" ", "");
Integer p1 = Integer.valueOf(tmp);
Integer p2 = Integer.valueOf(tmp2);
return p1.compareTo(p2);
}
I still have an error, but when I just take off " €" the value is "5 300 000", if only spaces "5300000€". But putting both together gives me this error java.lang.NumberFormatException: Invalid int: "-" ... Any ideas ? Thanks
You can make modify your Product class to implement Comparable
Before converting the String to an Integer you need to remove the €and all spaces.
public class Product implements Parcelable, Comparable<Product> {
private String prix;
//...
#Override
public int compareTo(Product otherProduct) {
String tmp = prix.replace(" €", "").replaceAll(" ", "");
String tmp2 = otherProduct.prix.replace(" €", "").replaceAll(" ", "");
Integer p1 = Integer.valueOf(tmp);
Integer p2 = Integer.valueOf(tmp2);
return p1.compareTo(p2);
}
}
Once done to sort your collection you can use : Collections.sort(...); this method will take as parameter the list of custom objects you are using in your adapter.
For example:
List<Product> l = new ArrayList();
Collections.sort(l);
Note that sorting the collection will not refresh the views of the recyclerview.
You will have to call notifyDataSetChanged() on your adapter to refresh the recyclerview:
You can do this in your main activity where you have declared your adapter :
yourAdapter.notifyDataSetChanged();
Just assuming you have List<String> sampleData object
Collections.sort(sampleData, new Comparator<String>() {
#Override
public int compare(String c1, String c2) {
return Integer.valueOf(c1) - Integer.valueOf(c2);
}
});
This will sort your data.
(int) Integer.parseInt(p2.getNumberOfRecords()) - Integer.parseInt(p1.getNumberOfRecords())
So the simple compare of an integer in a String data type would not result correctly but to parse the string first by:
int value = Integer.parseInt(string)
Try this:
Collections.sort (list, new Comparator<String> () {
#Override
public int compare (String s1, String s2) {
return s1.compareToIgnoreCase(s2);
}
});
OR
Collections.sort (list, new Comparator<String> () {
#Override
public int compare (String s1, String s2) {
//cast string price to integer
int price1 = Integer.parseInt(s1);
int price2 = Integer.parseInt(s2);
if (price1 > price1) {
return 1;
}
else if (price2 > price1) {
return -1;
}
else {
return 0;
}
}
});
I m using this framework, I already trying many times for making this problem, but I cant do it. I already asking on stackoverflow but no one cant help me. Actually I m tried.
I m using this framework : https://github.com/kikoso/Swipeable-Cards
And I m using SimpleCardStackAdapter like this :
for (int i = 0; i < user.length(); i++) {
final JSONObject c = user.getJSONObject(i);
// Storing JSON item in a Variable
String id = c.getString(user_id);
String name = c.getString(username);
final String email = c.getString(text);
String image1 = c.getString(imageUrl);
String range1 = c.getString(range);
String msgId = c.getString(postId);
// adapter.add(new CardModel(name, email, image1));
//Set JSON Data in TextView
Log.i("image1image1image1image1", image1);
// CardModel cardModel = new CardModel(" cardModel", " CardModel", r.getDrawable(R.drawable.picture1));
card = new CardModel(name, email, image1);
card.setOnClickListener(new CardModel.OnClickListener() {
#Override
public void OnClickListener() {
Log.i("Swipeable Cards", "I am pressing the card");
// Intent no = new Intent(HomeListview.this, YayDetailActivity.class);
/// startActivity(no);
}
});
card.setOnCardDimissedListener(new CardModel.OnCardDimissedListener() {
#Override
public void onLike(CardModel card) {
Log.i("Swipeable Cards", "I dislike the card");
}
#Override
public void onDislike(CardModel card) {
Log.i("Swipeable Cards", "I like the card");
// new sendNewYay().execute(sharedToken, card.getTitle());
Toast.makeText(getApplicationContext(), card.getDescription(), Toast.LENGTH_SHORT).show();
}
});
// I m added adapter
adapter.add(card);
mCardContainer.setAdapter(adapter);
}
At the onDislike method, I need to get item name.
in this line : new sendNewYay().execute(sharedToken, name);
I send the item name, But it dont work.
1.How can I get the item name, in this method?
2.I have two button, one of them for onLike method, another one for onDislike Method. Ho can I triggered this two method with my button?
Thank you.
Decleare two variable global as string
String itemname;
try {
JSONArray c = new JSONArray(user.toString());
for (int i = 0 ; i < c.length();i++) {
String id = c.getString(user_id);
String name = c.getString(username);
final String email = c.getString(text);
String image1 = c.getString(imageUrl);
String range1 = c.getString(range);
String msgId = c.getString(postId);
System.out.println("Position : " + "" + i + ""+ c.getString(i));
itemname = name.getString(i);
}
} catch (JSONException e) {
e.printStackTrace();
}
System.out.println("Final itemname is " + itemname);
I have a Comparator to sort by 3 values:
ORDER_BY_Points
ORDER_BY_Gdif // goals difference
ORDER_BY_Goals
First I get a array from a json string. I send the array to StandingsSort.ORDER_BY_RULES
Arrays.sort(addressArray, StandingsSort.ORDER_BY_RULES);
Here is my code:
static final Comparator<Standings> ORDER_BY_Points = new Comparator<Standings>() {
public int compare(Standings a1, Standings a2) {
return a1.points.compareTo(a2.points);
}
};
static final Comparator<Standings> ORDER_BY_Gdif = new Comparator<Standings>() {
public int compare(Standings a1, Standings a2) {
return a1.Gdif.compareTo(a2.Gdif);
}
};
static final Comparator<Standings> ORDER_BY_Goals = new Comparator<Standings>() {
public int compare(Standings a1, Standings a2) {
return a1.goalsP.compareTo(a2.goalsP);
}
};
static final Comparator<Standings> ORDER_BY_RULES = new Comparator<Standings>() {
public int compare(Standings a1, Standings a2) {
int i = ORDER_BY_Points.compare(a1,a2);
if(i == 0){
i = ORDER_BY_Gdif.compare(a1,a2);
if(i == 0){
i = ORDER_BY_Goals.compare(a1,a2);
}
}
return i;
}
};
class Standings {
String teamName;
String goalsP;
String goalsM;
String Gdif;
String points;
#Override
public String toString() {
return "" + teamName + "," + goalsP + ":" + goalsM + "," + Gdif + "," + points + "";
}
public Standings(String teamName, String goalsP,
String goalsM, String Gdif, String points) {
super();
this.teamName = teamName;
this.goalsP = goalsP;
this.goalsM = goalsM;
this.Gdif = Gdif;
this.points = points;
}
}
But the result is not OK! Here is the result
Name, Goals, GDif, Points
Team,11:9,2,10
Team,5:3,2,10
Team,9:2,7,11
Team,0:6,-6,2
Team,3:9,-6,2
Team,6:9,-3,3
Team,8:13,-5,3
Team,8:9,-1,5
Team,8:11,-3,5
Team,8:7,1,5
Why does the Comparator sort wrong?
Since you store the points as Strings, "10" comes before "2", "3", and "5". If you want to compare these in order by the numerical value, you need to convert them into ints first.
Similarly, Gdif and Goals are compared as Strings which is probably not what you want.
I filled array list with values. Each row is item with properties. Now I would like to sort items by one of properties and "print" them to textview.
ArrayList<String[]> arrayList = new ArrayList<String[]>();
final String[] rowToArray = new String[7];
rowToArray[0] = itemName;
rowToArray[1] = itemProperties1;
rowToArray[2] = itemProperties2;
rowToArray[3] = itemProperties3;
rowToArray[4] = itemProperties4;
rowToArray[5] = itemProperties5;
rowToArray[6] = itemProperties6;
arrayList.add(rowToArray);
Could you please help me to sort it by properties and then show me how to print item one by one with properties.
Thank you in advance.
EDIT:
SOLVED BY ppeterka66
I just had to add his code and call Collections.sort(arrayList,new StringArrayComparator(column)); where column is required column to be sortby.
int i=0;
final int column=2;
Collections.sort(arrayList,new StringArrayComparator(column));
for(String[] line :arrayList)
{
Log.d(Integer.toString(i),line[column].toString());
}
Collections.sort
for example
class User {
String name;
String age;
public User(String name, String age) {
this.name = name;
this.age = age;
}
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
import java.util.Comparator;
public class ComparatorUser implements Comparator {
public int compare(Object arg0, Object arg1) {
User user0 = (User) arg0;
User user1 = (User) arg1;
int flag = user0.getAge().compareTo(user1.getAge());
if (flag == 0) {
return user0.getName().compareTo(user1.getName());
} else {
return flag;
}
}
}
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class SortTest {
public static void main(String[] args) {
List userlist = new ArrayList();
userlist.add(new User("dd", "4"));
userlist.add(new User("aa", "1"));
userlist.add(new User("ee", "5"));
userlist.add(new User("bb", "2"));
userlist.add(new User("ff", "5"));
userlist.add(new User("cc", "3"));
userlist.add(new User("gg", "6"));
ComparatorUser comparator = new ComparatorUser();
Collections.sort(userlist, comparator);
for (int i = 0; i < userlist.size(); i++) {
User user_temp = (User) userlist.get(i);
System.out.println(user_temp.getAge() + "," + user_temp.getName());
}
}
}
You could create a reusable String[] Comparator you could specify which indexes to compare the arrays on:
public class StringArrayComparator implements Comparator<String[]> {
//we store the index to compare the arrays by in this instance variable
private final int stringIndexToCompare;
//constructor accepting the value for the index to check
public StringArrayComparator(int whichString) {
stringIndexToCompare=whichString;
}
#Override
public int compare(String[] o1, String[] o2) {
//checking if any of the arrays is null
if(o1==null) { return o2==null?0:1; } //if o1 is null, o2 determines the resuult
else if(o2==null) { return -1; } //this only gets evaluated if o1 is not null
//get the strings, by checking if the arrays are long enough
String first = o1.length>stringIndexToCompare?o1[stringIndexToCompare]:null;
String second= o2.length>stringIndexToCompare?o2[stringIndexToCompare]:null;
//null checking the strings themselves -- basically same as above
if(first==null) { return second==null?0:1; }
else if(second==null) { return -1; }
//if both non-null, compare them.
return first.compareTo(second);
}
}
To be used on your list:
Collections.sort(myList,new StringArrayComparator(3));
Note: the 3 specifies the index of the array to be compared.
You didn't specify the expected output of how the printed string should look, but just to print the list, you could use this oneliner:
System.out.println(Arrays.deepToString(a.toArray()));
EDIT
I would like to see something like Log.d("line number",column[0]+","+column1+","+column[2]+...);
Hey, that looks almost OK... Basically you only have to put it into a loop: this prints it line by line:
int lineNo=0;
for(String[] line :myList) {
StringBuilder sb = new StringBuilder();
sb.append(++i); //line number, incrementing too
//iterating through the elements of the array
for(int col=0;col<line.lenght;col++) {
sb.append(",");
if(line[col]!=null) { //check for null....
sb.append(line[col]);
}
}
Log.d(sb.toString()); //append the value from the builder to the log.
}
To get it in one big string:
int lineNo=0;
StringBuilder sb = new StringBuilder(); //create it here
for(String[] line :myList) {
sb.append(++i); //line number, incrementing too
//iterating through the elements of the array
for(int col=0;col<line.lenght;col++) {
sb.append(",");
if(line[col]!=null) { //check for null....
sb.append(line[col]);
}
}
sb.append("\n"); //append line break
}
Log.d(sb.toString()); //append the value from the builder to the log.
Or, maybe it would be nicer (though slower) to use String.format() for this purpose,a s that offers better formatting:
//assembly format string
//if no line number was needed: String format = "";
String format = "%d"; //line number, %d means integer
for(int i=0;i<7;i++) {
format+=",%20s"; //%20s means left aligned, 20 wide string
}
format += "\n"; //line break;
int lineNumber=0;
for(String[] line:myArray) {
//if you didn't need the line number, it would be so easy here
//String.format(format,line); //one line, but this doesn't have the line number yet...
//with line numbers:
int iamLazyNow = 0;
String formatted = String.format(format,++lineNumber,
line[iamLazyNow++], line[iamLazyNow++],
line[iamLazyNow++], line[iamLazyNow++],
line[iamLazyNow++], line[iamLazyNow++],
line[iamLazyNow++]); //practically one line, but ugly
//you can append formatted to a StringBuilder, or print it here...
}
I've been looking for a way to capture the order of element's listed within a tag, but haven't been very successful..
EDIT NEW:
<android>
<leags>
<leag name = "someName">
<headlines>
<pageType>headlines</pageType>
<story>someStoryURL</story>
<fullStory>someFullStoryURL</fullStory>
</headlines>
<scores></scores>
<statistics></statistics>
</leag>
<leags>
</android>
-Want to capture the order of elements in leag as 1)headlines 2)scores 3)statistics. If the xml changes and scores is listed before headlines it would be 1)scores 2)headlines 3)statistics.
I parse only android - Like this:
#Root(name = "android", strict = false)
public class android
{
#ElementList(name = "leags", required = false)
private List<Leag> leags;
public Leag getLeagByName(String name)
{ // go through list of leags and return leag with matching name}
}
So in my "leag" object I'd want to capture the order of elements - Is there a way to do that?
I'm assuming you'd need to set new AnnotionStrategy() like this:
tAndroid android = null;
Serializer serial = new Persister(new AnnotationStrategy());
android = serial.read(android .class, source);
League x= android.getLeagueByName("oeoe");
for(String s: x.getOrder())
{
Log.i("Order", s);
}
BEFORE EDIT:
Supposing the xml above is what's being pased by the following code:
#Element(name="headlines")
public class Headlines
{
#Element(name="pageType", required = false)
private String pageType;
#Element(name="story", required = false)
private String storiesURL;
#Element(name="fullStory", required = false)
private String fullStoryURL;
public String getStoriesURL()
{
return storiesURL;
}
public String getFullStoryURL()
{
return fullStoryURL;
}
#Override
public String toString()
{
return "PageType: " + this.pageType +
"\nStoriesURL: " + this.storiesURL +
"\nFullStoryURL: " + this.fullStoryURL;
}
}
Is there a way to somehow return the order in which the elements get parsed?
Like a method that will return a string of some sort with the correct order like:
pageType
story
fullStory
You can use a Converter to get the order. But you can't return the order from it (or better: you can, but better don't do it).
It's relatively easy to get the order - the trick is getting it out from the Converter. On way is to add a list to your class and store it there.
Implementation:
#Root(name = "headlines")
#Convert(value = Headlines.HeadlinesConverter.class)
public class Headlines
{
#Element(name="pageType", required = false)
private String pageType;
#Element(name="story", required = false)
private String storiesURL;
#Element(name="fullStory", required = false)
private String fullStoryURL;
private List<String> order; // Here we save the order of the elements
public String getPageType()
{
return pageType;
}
public String getStoriesURL()
{
return storiesURL;
}
public String getFullStoryURL()
{
return fullStoryURL;
}
public List<String> getOrder()
{
return order;
}
#Override
public String toString()
{
return "Headlines{" + "pageType=" + pageType
+ ", storiesURL=" + storiesURL
+ ", fullStoryURL=" + fullStoryURL + '}';
}
// You can implement the converter as an extra class too
static class HeadlinesConverter implements Converter<Headlines>
{
#Override
public Headlines read(InputNode node) throws Exception
{
Headlines h = new Headlines();
h.order = new ArrayList<>(3);
InputNode next = node.getNext();
while( next != null )
{
final String value = next.getValue();
/*
* You can use reflection (= slower) instead the switch, or
* remove the switch:
*
* h.order.add(next.getName());
*
* and do this after the while loop:
*
* h.pageType = node.getNext("pageType");
* ...
*/
switch(next.getName())
{
case "pageType":
h.pageType = value;
break;
case "story":
h.storiesURL = value;
break;
case "fullStory":
h.fullStoryURL = value;
break;
default:
/* Maybe some error-handling here?! */
break;
}
h.order.add(next.getName()); // add 'value' if you want the order of the values
next = node.getNext();
}
return h;
}
#Override
public void write(OutputNode node, Headlines value) throws Exception
{
throw new UnsupportedOperationException("Not supported yet.");
}
}
}
Note: I didn't use setter here - but it's better you do so.
Example code:
final File f = new File("test.xml");
Serializer ser = new Persister(new AnnotationStrategy()); /* ! */
Headlines h = ser.read(Headlines.class, f);
int i = 1;
for( String s : h.getOrder() )
{
System.out.println((i++) + ". " + s);
}
and finally the output:
1. pageType
2. story
3. fullStory
You need to use #Order annotation. Here can see an example http://simple.sourceforge.net/download/stream/doc/tutorial/tutorial.php#xpath