Add equal values in a ArrayList in Android - java

I am storing scores in a ArrayList, but when the user has a score equal to a previous score, the second one is not added to the ArrayList. How can I add equal values to a ArrayList (or use another type of List)?
Code:
[...]
ArrayList<String> savedArray = new ArrayList<>();
Set<String> gandula = new HashSet<>();
[...]
public Preferencias(Context contextoParametro) {
contexto = contextoParametro;
preferences = contexto.getSharedPreferences(NOME_ARQUIVO, MODE);
editor = preferences.edit();
}
public void addMediaGeral(double mediaGeral) {
//Save Score
Set<String> set = new HashSet<String>();
if (!getMediaGeral().get(0).equals("0")) {
savedArray.addAll(getMediaGeral());
}
savedArray.add(String.valueOf(mediaGeral));
set.addAll(savedArray);
editor.putStringSet(KEY_MEDIA_GERAL, set);
editor.commit();
}
public ArrayList<String> getMediaGeral(){
//get score
Set<String> set = preferences.getStringSet(KEY_MEDIA_GERAL, gandula);
ArrayList<String> list = new ArrayList<String>(set);
return list;
}
[...]
Retrieving in my activity:
[...]
mediaGeral = score;
preferencias.addMediaGeral(Double.parseDouble(mediaGeral));
[...]
ArrayList<String> string_medias = new ArrayList<>();
string_medias = preferencias.getMediaGeral();
ArrayList<Float> float_medias = new ArrayList<>();
for (int j = 0; j < string_medias.size(); j++){
float_medias.add(Float.parseFloat(string_medias.get(j)));
}
Log.i("TESTANDO PRF", "TAMANHO DA LISTA: "+float_medias.size());
Float[] dataObjects = float_medias.toArray(new
Float[float_medias.size()]);
doChart(float_medias);
[...]
I scored 0.33333 three times (I'll config decimal places) but it is showing only one score 0.3333.
Printscreen: http://prntscr.com/f1vx3h
But the chart accepts duplicates. Printscreen: http://prntscr.com/f1vxng (i manipulated the scores in the last printscreen).

A Set does not allow for duplicate values.
Doing this:
set.addAll(savedArray);
discards all your duplicates.
These answers may be of help.
Saving a JSON object as a string in preferences would probably be the way to go.

ArrayList accept duplicate this should not be your problem but I saw that your store yours score in a HashSet uses a hashMap instead because:
In the case of HashMap, it replaces the old value with the new one.
In the case of HashSet, the item isn't inserted.

Related

Push values to a map when key is already exisitng in a map

I have declared a map as below:
Map<String, String[]> test = new HashMap<String, String[]>();
I have a variable empnames which is an array and deptname is a String and i have declared the deptname and empnames as below:
String deptname = ['Department']
String empnames = [['Test1']['Test2']]
if (deptname != null)
{
if (test.containsKey(deptname))
{
///
}
else
{
test.put(deptname, new String[]{empnames});
}
}
If the test map already contains deptname key then what condition i should write in if condition to append new values to department?
Since you tagged for [grails], I assume a Groovy answer is appropriate too. You can use a Map with .withDefault{ ... } to provide the content in case the key is missing. E.g.
def data = [["x", ["a", "b"]], ["x", ["c", "d"]]]
def test = [:].withDefault{[]} // XXX
data.each{ k, vs ->
test[k].addAll(vs) // if there is no key `k`, create an empty array, so `.addAll` just works
}
println(test.inspect())
// => ['x':['a', 'b', 'c', 'd']]
You can use the new methods in Java 8 like putIfAbsent to add new entry if key is not present and computeIfPresent to append values to an existing key of a map.
An example would be:
public static void main(String[] args) {
Map<String, String[]> test = new HashMap<>();
String deptname = "Department";
String[] empnames = {"Test1", "Test2"};
if (deptname != null){
test.putIfAbsent(deptname, empnames);
test.computeIfPresent(deptname, (dept, value) -> {
List<String> list = new ArrayList<>(Arrays.asList(value));
list.add("Test3");
value = list.toArray(value);
return value;
});
}
for(String s : test.get("Department")){
System.out.println(s);
}
}
Here the putIfAbsent tests if the key is present, if not adds a new key-value entry. The computeIfAbsent on the other hand tests if the key is present, if yes it computes the new value for the existing key-value entry.
The output of the above code is:
Test1
Test2
Test3
This is because initially the key Department was not present in the map test, so it was added to it along with the value empnames as an array.
In the second operation the method computeIfPresent checked that the key Department was already in the map so it appended the new String Test3 to existing value array of [Test1, Test2].
The same can be done for an List instead of an array:
public static void main(String[] args) {
Map<String, List<String>> test = new HashMap<>();
String deptname = "Department";
List<String> empnames = new ArrayList(Arrays.asList("Test1", "Test2"));
if (deptname != null){
test.putIfAbsent(deptname, empnames);
test.computeIfPresent(deptname, (dept, value) -> {
value.add("Test3");
return value;
});
}
for(String s : test.get("Department")){
System.out.println(s);
}
}
ArrayList<String> departmentList;
if(test.containsKey(key)){
// if the key has already been used, then and add a new value to it
list = test.get(key);
list.add(value);
test.put(key, list);
} else {
// if the key hasn't been used yet, then create a new ArrayList<String> object, add the value
list = new ArrayList<String>();
list.add(value);
test.put(key, list);
}
As others have suggested, this would be easier if you had an ArrayList instead of String[].
But since you have a String[], you will have to make a new array of old_array's_size + list_to_add and copy over the values from the old array into the new one plus the new value you want to append.
So inside of your if statement:
String [] oldList = test.get(deptName);
String[] newList = new String[oldList.length + empnames.length]; //Make a new array with enough space for the previous values at deptname but also the new ones you want to add
//Put all of the values from the existing value at deptname into a new array
for (int i = 0; i < oldList.length; i++)
newList[i] = oldList[i];
//Put all of the values from the list of values you want to add into the new array
for (int i = 0; i < empnames.length; i++)
newList[oldList.length + i] = empnames[i];
test.put(deptname, newList); //Put the completed list back into the map
Again, if you used some kind of List this would be easier. One good reason besides being able to append is that you can easily sort it alphabetically using Collections.sort.

List of List String in java

I have a problem with the implementation of List>, it gives me always the last element duplicated. Here is a bunch of my code :
Here is the declaration of my list and the list of lists.
public List<List<String>> survs = new ArrayList<>();
public List<String> surveillance = new ArrayList<>();
public int k=0;
Here i add to the list some strings.
public void handleAddSURVClick(ActionEvent actionEvent) {
survName = name.getText();
max = maxp.getText();
min = minp.getText();
surveillance.add(survName);
surveillance.add(monitoredObject);
surveillance.add(monitoredProperty);
surveillance.add(max);
surveillance.add(min);
// Add surveillance to the vector
survs.add(k, surveillance);k++;
//Surv initialisation
survName = ""; name.clear();
max = ""; maxp.clear();
min = ""; minp.clear();
monitoredObject = "";
monitoredProperty = "";
}
then simply i add the list to the list of lists and i specify an index in which i wanna store my list and i print the list of lists ( survs )
survs.add(k, surveillance);k++;
System.out.println(survs);
Unfortunately, it gives me this result after submitting two lists, it gives just the last one redundant:
[[yas, ProductSurrounding, charge, 667, 524, stack, ProductSurrounding, charge, 8787, 6422], [yas, ProductSurrounding, charge, 667, 524, stack, ProductSurrounding, charge, 8787, 6422]]
if i do surveillance.clear(), the results will be two empty lists [[],[]]
Thank you in advance
Create new instance of surveillance after each time you add it to the survs.But crate survs this instance only once.
Do like this :
public void handleAddSURVClick(ActionEvent actionEvent) {
survName = name.getText();
max = maxp.getText();
min = minp.getText();
surveillance=new ArrayList<>();
surveillance.add(survName);
surveillance.add(monitoredObject);
surveillance.add(monitoredProperty);
surveillance.add(max);
surveillance.add(min);
// Add surveillance to the vector
survs.add(k, surveillance);k++;
//Surv initialisation
survName = ""; name.clear();
max = ""; maxp.clear();
min = ""; minp.clear();
monitoredObject = "";
monitoredProperty = "";
}
And if you do surveillance.clear() then you are clearing the value in the reference of surveillance in your survs.So at the end all becomes empty.

How to get equal or close to equal amount of objects with different field values from ArrayList

For Example I have ArrayList with Objects.
This objects have some field - pictureName.
One of them really have picture name (lets name them "1st type"), other have just an empty string (2nd type).
size of arrayList = M and can change.
Amount of 1st and 2nd-type objects can be different.
I need to get equal or close to equal amount of 1st type objects and 2nd type objects and add them into another (empty) arraylist. Size of this arraylist is N, and N<=M.
What is the better way to do this?
UPD: I can't set the size of new ArrayList. I just can find out this number (user sets it). But N<=M is always true
Edit
OP clarified their requirements so I have updated my code. I still begin by sectioning into two lists as below, but then I build the final list as follows:
Iterator<MyObject> namesIterator = withNames.iterator();
Iterator<MyObject> noNamesIterator = noNames.iterator();
while (newList.size() < userDefinedSize) {
if (namesIterator.hasNext()) {
newList.add(namesIterator.next());
}
if (noNamesIterator.hasNext() && newList.size() < userDefinedSize) {
newList.add(noNamesIterator.next());
}
}
Original
My strategy is to iterate over the original list and bucket the objects by whether they have a pictureName or not. Then create a new list, and add to that list from my buckets until I use up all the elements in the smallest bucket.
private void myMethod() {
List<MyObject> original = /* your code here */
List<MyObject> withNames = new ArrayList<>();
List<MyObject> noNames = new ArrayList<>();
for (MyObject o : original) {
if (o.pictureName != null) {
withNames.add(o);
}
else {
noNames.add(o);
}
}
int size = Math.min(withNames.size(), noNames.size());
List<MyObject> newList = new ArrayList<>(size);
for (int i = 0; i < size; i++) {
newList.add(withNames.get(i));
newList.add(noNames.get(i));
}
// now you have the same number of named and unnamed objects in `newList`
}

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);
}

Java HashMap content seems to change without changing it

I have a problem concerning a HashMap in Java. To explain the problem in a detailed way, i will first post some code you can refer to.
public void BLASTroute(String args[]) throws IOException, InterruptedException{
...
correctMapping CM = new correctMapping();
CM.correctMapping(RB.BLASTresults, exists);
CalculateNewConsensusSequence CNCS =
new CalculateNewConsensusSequence();
char[] consensus = CNCS.calculateNewConsensusSequence(
CM.newSeq, CM.remindGaps, EMBLreaderReference.sequence, exists);
HashMap<Integer, ArrayList<String>> gapsFused =
new HashMap<Integer, ArrayList<String>>();
for (Integer i : CM.remindGaps.keySet()) {
ArrayList<String> newList = CM.remindGaps.get(i);
gapsFused.put(i, newList);
}
GenerateGeneLists GGL = new GenerateGeneLists(
EMBLreaderReference, CM.newSeq, gapsFused, exists,
GQList, allMappedPositions);
System.out.println(CM.remindGaps.hashCode());
gapsFused=GGL.generateGeneListSNP(gapsFused);
System.out.println(CM.remindGaps.hashCode());
System.out.println(gapsFused.hashCode());
GGL.generateGeneListFrameShift(gapsFused);
}
The following occurs:
in my class correctMapping, i fill a global variable called remindGaps. I use it later in some functions, and nothing happens/everything works as expected.
Then, i make a copy of the HashMap called gapsFused (i don't know if this has something to do with my problem).
Now comes the interesting part: In the class GenerateGeneLists, i don't do a thing with the remindGaps HashMap.
However, after the function generateGeneListSNP is performed, remindGaps changed! I'll post the code for you as well, so that you can help me better:
public GenerateGeneLists(EMBL_reader EMBLreaderReference,
HashMap<String,ArrayList<String>> newSeq,
HashMap<Integer,ArrayList<String>> gapsFused, File exists,
ArrayList<GeneQualifier> GQlist,
HashMap<Integer,Integer> allMappedPositions)
throws InterruptedException{
this.EMBLreaderReference=EMBLreaderReference;
this.newSeq=newSeq;
//this.gapsFused=gapsFused;
this.exists=exists;
this.GQlist=GQlist;
this.allMappedPositions=allMappedPositions;
for (GeneQualifier GQ : this.GQlist){
startlist.add(GQ.start);
stoplist.add(GQ.stop);
startMap.put(GQ.start,GQ);
}
}
public HashMap<Integer,ArrayList<String>> generateGeneListSNP(
HashMap<Integer,ArrayList<String>> gapsFused)
throws IOException{
File GQSNP = new File (exists+"/GQsnp.txt");
BufferedWriter SNP = new BufferedWriter(new FileWriter(GQSNP));
SNP.write("#Gene_start\tGene_stop\tlocus_tag\tproduct" +
"\tputative_SNP_positions(putative_changes)\n");
HashMap<GeneQualifier,ArrayList<Integer>> GQreminder =
new HashMap<GeneQualifier,ArrayList<Integer>>();
for (String s : newSeq.keySet()){
ArrayList<String> blub = newSeq.get(s);
char[] qrySeq = blub.get(0).toCharArray();
char[] refSeq = blub.get(1).toCharArray();
int start = Integer.valueOf(blub.get(2));
int stop = Integer.valueOf(blub.get(3));
for (int i=0;i<refSeq.length;i++){
if (qrySeq[i]!=refSeq[i]&&qrySeq[i]!='-'&&qrySeq[i]!='.'){
if (mismatchList.containsKey(start+i)){
ArrayList<Character> blah = mismatchList.get(start+i);
blah.add(qrySeq[i]);
mismatchList.put(start+i, blah);
}
else {
ArrayList<Character> blah = new ArrayList<Character>();
blah.add(qrySeq[i]);
mismatchList.put(start+i,blah);
}
}
else if (qrySeq[i]!=refSeq[i]&&(qrySeq[i]=='-'||qrySeq[i]=='.')){
if (!gapsFused.containsKey(start+i)){
ArrayList<String> qwer = new ArrayList<String>();
qwer.add(String.valueOf(qrySeq[i]));
gapsFused.put(start+i,qwer);
}
else {
ArrayList<String> qwer = gapsFused.get(start+i);
qwer.add(String.valueOf(qrySeq[i]));
gapsFused.put(start+i,qwer);
}
if (!deletionPositionsAndCount.containsKey((start+i))){
int count = 1;
deletionPositionsAndCount.put(start+i, count);
}
else {
int count = deletionPositionsAndCount.get(start+i);
count = count+1;
deletionPositionsAndCount.put(start+i, count);
}
}
}
}
for (Integer a : mismatchList.keySet()){
for (int i=0;i<startlist.size();i++){
int start = startlist.get(i);
int stop = stoplist.get(i);
if (a>=start && a<=stop){
GeneQualifier GQ = startMap.get(start);
if (!GQreminder.containsKey(GQ)){
ArrayList save = new ArrayList<Integer>();
save.add(a);
GQreminder.put(GQ,save);
}
else {
ArrayList save = GQreminder.get(GQ);
save.add(a);
GQreminder.put(GQ,save);
}
break;
}
}
}
for (GeneQualifier GQ : GQreminder.keySet()) {
ArrayList<Integer> save = GQreminder.get(GQ);
int start = GQ.start;
int stop = GQ.stop;
String locus_tag =
GQ.geneFeatures.get("locus_tag").get(0).replace("\n", "");
String product =
GQ.geneFeatures.get("product").get(0).replace("\n", "");
SNP.write(start + "\t" + stop + "\t" + locus_tag +
"\t" + product + "\t");
boolean end = false;
for (int i = 0; i < save.size(); i++) {
if (i==save.size()-1) end=true;
int posi = save.get(i);
SNP.write(posi + "(");
ArrayList<Character> mismatches = mismatchList.get(posi);
for (int j = 0; j < mismatches.size(); j++) {
char snipp = mismatches.get(j);
if (j == mismatches.size() - 1) {
SNP.write(snipp + ")");
} else {
SNP.write(snipp + ",");
}
}
if (end == false){
SNP.write(",");
}
}
SNP.write("\n");
}
SNP.close();
return gapsFused;
}
As you can see, remindGaps is not used in this class, but still it undergoes changes. Do you have an idea why this is the case?
What I tested is, whether remindGaps changes if i manually change gapsFused (the made copy of the first HashMap). This is not the case, so i don't think that the copying process went wrong (for example only points to the other HashMap or references it).
I would really appreciate your ideas and help in order to solve this problem.
You have to remember that in Java all objects are passed as reference. So, when you did:
ArrayList<String> newList = CM.remindGaps.get(i);
you basically pointed newList to the same list as contained in the remindGaps map. Now, even though you work with the gapsFused, any changes to its values effect the same underlying list in the memory - to which both remindGaps and gapsFused are pointing.
Change your copy code to the following and see if it makes a difference:
ArrayList<String> newList = new ArrayList<String>(CM.remindGaps.get(i));
By doing this, you are creating a new list that newList will be pointing to and thus the changes will be encapsulated.
Your code is very long and hard to read (mainly because it doesn't respect Java naming conventions), but my guess is that your problem comes from the fact that your copy of the map simply copies the ArrayList references from one map to another:
HashMap<Integer, ArrayList<String>> gapsFused = new HashMap<Integer, ArrayList<String>>();
for (Integer i : CM.remindGaps.keySet()) {
ArrayList<String> newList = CM.remindGaps.get(i);
gapsFused.put(i, newList);
}
In the above code, you don't create any new list. You just store the same lists in another map. If you need a new list, the code should be:
Map<Integer, List<String>> gapsFused = new HashMap<Integer, List<String>>();
for (Integer i : CM.remindGaps.keySet()) {
List<String> newList = new ArrayList<STring>(CM.remindGaps.get(i));
gapsFused.put(i, newList);
}
Without analyzing all your code:
HashMap<Integer, ArrayList<String>> gapsFused = new HashMap<Integer, ArrayList<String>>();
for (Integer i : CM.remindGaps.keySet()) {
ArrayList<String> newList = CM.remindGaps.get(i);
gapsFused.put(i, newList);
}
After this code gapFused will contain entries that are copies of the entries of remindGaps, therefore those entries will reference the same objects (key and values). So if you add or remove entries in one Map it will have no effect on the other, but if you change a value accessing it through one Map you will see the change also accessing it through the other map (for example remingGaps.get(1).add("hello")).
The name "newList" used in your code is confusing because it is not a new list, just a reference on an existing one...
Since the value of the Map is an ArrayList and you are doing just a shallow copy (meaning the new Map has a reference to the same Lists as are in the first Map) and changes to the lists in the second map would be reflected in the first map. To avoid this you would need to make deep copies of the lists when you create the new Map.

Categories

Resources