Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions concerning problems with code you've written must describe the specific problem — and include valid code to reproduce it — in the question itself. See SSCCE.org for guidance.
Closed 9 years ago.
Improve this question
I am trying to write 3 methods say
1. getAddedTasks()
2. getRemovedTasks()
3. saveTasks()
get it done for the following
there two hashmap
1. is onscreen and 2. actual
onscreen: {} , actual: {}
step 1 : i have to use add button to add 3 tasks, 1,2,3 in onscreen , and actual will be empty
like this
onscreen: {1,2,3}, actual: {}
step 2 : when click save click save ->this shoul happen
getRemovedTasks()="", getAddedTasks()="1,2,3"
then hashmap status will be like this
onscreen: {1,2,3}, actual: {1,2,3}
step 3 : again i want add 4th value in onscreen
like this
onscreen: {1,2,3,4}, actual: {1,2,3}
simultaneously i want remove 3rd value
like this
onscreen: {1,2,4}, actual: {1,2,3}
step 4 : click save -> getRemovedTasks()="3", getAddedTasks()="4"
finally output should be like this
onscreen: {1,2,4}, actual: {1,2,4}
i tried with this following code
import java.util.*;
public class getList
{
private static HashMap<Integer, Object[]> dataz = new HashMap<Integer,Object[]>();
private static HashMap<Integer, Object[]> screen_dataz = new HashMap<Integer,Object[]>();
public final static Object[][] longValues = {{"10", "kstc-proc", "10.10.","5","O"},{"11", "proc-lvk1", "12.1.2.","4","O"},{"13", "trng-lvk1", "4.6.1.","3","O"}};
public static String sl, pid, tid, mval,status;
public static String findRowsRemoved()
{
ArrayList<String> datazList = new ArrayList<String>();
for(int index: dataz.keySet())
{
Object[] data = dataz.get(index);
datazList.add(data[1]+":"+data[2]);
}
for (int index: screen_dataz.keySet())
{
Object[] data = screen_dataz.get(index);
String check = data[1]+":"+data[2];
if (datazList.contains(check))
datazList.remove(check);
}
HashMap<String,String> p = new HashMap<String,String>();
for(String d: datazList)
{
String pId = d.split(":")[0];
String tId = d.split(":")[1];
if (p.containsKey(pId))
p.put(pId, p.get(pId)+","+tId);
else
p.put(pId, tId);
}
String fullStr = "";
for(String pId: p.keySet())
{
fullStr += pId + ":" + p.get(pId) + "|";
}
fullStr = fullStr.substring(0, fullStr.length()-1);
return fullStr;
}
public static void addTask(HashMap<Integer,Object[]> d, Object[] data)
{
d.put(screen_dataz.size(), data);
}
public static void saveTask()
{
System.out.println("Save Task");
System.out.println("-------------");
dataz.putAll(screen_dataz);
for (int i=0; i<longValues.length; i++)
{
for (int j=0; j<longValues.length; j++)
{
sl = (String) longValues[i][0];
pid = (String) longValues[i][1];
tid = (String) longValues[i][2];
mval = (String) longValues[i][3];
status = (String) longValues[i][4];
}
}
}
public static void main(String args[])
{
//addTask();
Object[] obj = new Object[5];
String[] strArray = new String[]{"1","kstc-proc","1.1","5","O"};
String[] strArray1 = new String[]{"2","proc-lvk1","1.2.","6","O"};
String[] strArray2 = new String[]{"3","proc-lvk1","1.3.","7","O"};
addTask(screen_dataz, strArray);
addTask(screen_dataz, strArray1);
addTask(screen_dataz, strArray2);
Object[] obj1= new Object[5];
String[] strArray3 = new String[]{"4","kstc-proc","1.4","8","O"};
addTask(dataz, strArray2);
addTask(dataz, strArray3);
String str = findRowsRemoved();
System.out.println("RowsRemoved: " + str);
str = findRowsAdded();
System.out.println("RowsAdded: " + str);
//saveTask();
}
}
public class multivalueHashmap {
private Map< Integer, List<Float> > map = new HashMap< Integer, List<Float> >();
public void add(Integer id, Float value){
if(!map.containsKey(id)){
map.put(id, new ArrayList<Float>());
}
map.get(id).add(value);
}
public void delete(Integer id, Float value){
if(!map.containsKey(id)){
return;
}
map.get(id).remove(value);
}
}
This way you can use the methods to easily add and remove items.
Related
The input is String array as below,
{"1112323 400 error","1112323 400 error","9988778 400 error"}
I need to print the timestamp i.e the number at the start of the sentences and its frequency throughout the array
I've come only this far as of now. Only have been able to find the string if it is known already.
int count = 0;
for(int i=str1.length-1;i>=0;i--)
{
String[] ElementOfArray = str1[i].split(" ");
for(int j=0;j<ElementOfArray.length-1;j++)
{
if(ElementOfArray[j].equals("Hi"))
{
count++;
}
}
}
System.out.println(count);
One approach is to keep track of the number of entries, and increment.
public static void main(String[] args)
{
String[] inp = {"1112323 400 error",
"1112323 400 error",
"9988778 400 error"};
Map<String,Integer> results = new HashMap<>();
for (String one : inp) {
String[] parts = one.split(" ");
String ts = parts[0];
int val = results.computeIfAbsent(ts, v-> 0);
results.put(ts, ++val);
}
System.out.println(results);
}
Note: there are other ways to handle the map incrementing. This is just one example.
Sample Output:
{1112323=2, 9988778=1}
Now, if in the future one might want to perform other operations, using objects might be of interest.
So a class might be:
private static class Entry
{
private final String ts;
private final String code;
private final String desc;
public Entry(String ts, String code, String desc)
{
// NOTE: error handling is needed
this.ts = ts;
this.code = code;
this.desc = desc;
}
public String getTs()
{
return ts;
}
public static Entry fromLine(String line)
{
Objects.requireNonNull(line, "Null line input");
// NOTE: other checks would be good
String[] parts = line.split(" ");
// NOTE: should verify the basic parts
return new Entry(parts[0], parts[1], parts[2]);
}
// other getter methods
}
And then one could do something like:
List<Entry> entries = new ArrayList<>();
for (String one : inp) {
entries.add(Entry.fromLine(one));
}
Map<String,Integer> res2 = entries.stream()
.collect(Collectors.groupingBy(x->x.getTs(),
Collectors.summingInt(x -> 1)));
System.out.println(res2);
(same sample output at the moment). But if one needs to extend to count the number of 400 codes or whatever, it is trivial to change the stream since the object has the data. Of course, there are even more extensions to this approach.
You can use HashMap to solve count the frequency of timestamps.
import java.util.HashMap;
public class test {
public static void main(String[] args) {
// Create a HashMap object called timeFrequency
HashMap<String, Integer> timeFrequency = new HashMap<String, Integer>();
String []str1 = {"1112323 400 error","1112323 400 error","9988778 400 error"};
for(int i=0;i<str1.length;i++)
{
String[] ElementOfArray = str1[i].split(" ");
if(timeFrequency.containsKey(ElementOfArray[0])){
timeFrequency.put(ElementOfArray[0], timeFrequency.get(ElementOfArray[0]) + 1);
}else{
timeFrequency.put(ElementOfArray[0], 1);
}
}
System.out.println(timeFrequency);
}
}
Output:
{1112323=2, 9988778=1}
so i asked before but it seems i wasnt clear enough of what im talking about, so im trying to make it clearer now:
what im trying to do is prepare data for an import. the data i get is human made an not very efficient, so im removing unnecessary entrys and try to combine the data as much as possible.
its for something like a configurator. the data i get looks something like this:
123 : 45 : AB = 12
This means: if Option 1 is 1 OR 2 OR 3 and Option 2 is 4 OR 5 and Option 3 is A OR B the result will be 1 AND 2
i created a class thats something like this:
Class Options{
String opt1;
String opt2;
String opt3;
String optResult;
//and some other stuff
boolean hasSameOptions(Options o){
return opt1.equals(o.opt1) && opt2.equals(o.opt2) && opt3.equals(o.opt3);
}
public void AddOptions(String options) {
for (String s : options.split("")) {
if (!optResult.contains(s)) {
optResult = optResult + s;
}
}
}
}
now, the data is repetitive and can be combined. Like:
12 : 45 : AB = 12
12 : 45 : AB = 3
12 : 45 : AB = 4
This would mean actually mean: 12 : 45 : AB = 1234
So, what i do is break the Strings apart to get only single values with the result, for example:
1 : 4 : A = 12
1 : 4 : B = 12
1 : 5 : A = 12
//and so on.
I make a list of all these Values and then try to Combine them again to get more efficient List.
The first step i do is get all Objects who have the same Options but different Results and combine the results. that happens like this:
public static List<Options> cleanList(List<Options> oldList) {
List<Options> newList = new ArrayList<>();
for (Options item : oldList) {
Options temp = findEqualOptions(newList, item);
if (temp != null)
temp.AddOptions(item.optResult);
else
newList.add(item);
}
return newList;
}
public static <T> T findByProperty(Collection<T> col, Predicate<T> filter) {
return col.stream().filter(Objects::nonNull).filter(filter).findFirst().orElse(null);
}
public static Options findEqualOptions(List<Options> list, Options opt) {
return findByProperty(list, d -> d.hasSameOptions(opt));
}
After that, i try to compress the list even more, by combining elements who have only ONE different value. For example:
1 : 2 : A = 12
1 : 3 : A = 12
-> 1 : 23 : A = 12
i do it like this:
for (int i = 0; i < list.size(); i++) {
for (int j = i + 1; j < list.size(); j++) {
Option o1 = list.get(i);
Option o2 = list.get(j);
int diff1 = 0;
int diff2 = 0;
int diff3 = 0;
int diff4 = 0;
if(!o1.opt1.equals(o2.opt1))
diff1 = 1;
if(!o1.opt2.equals(o2.opt2))
diff2 = 1;
//and so on
if((diff1+diff2+diff3+diff4)>1)
continue;
if(diff1 == 1)
o1.opt1 = o1.opt1 + o2.opt1;
//and so on...
list.remove(j--);
}
}
i do this until there are no more changes. It works well, but slowly. especially the method cleanList().
does anybody have any idea how to make it better? i tried to use a stream to get the whole list of equals options directly like this:
public static <T> List<T> findByMultipleValue(Collection<T> col, Predicate<T> filter) {
return col.stream().filter(filter).collect(Collectors.toList());
}
public static List<Options> getEqualOptionsList(List<Options> optList, Options opt){
return findByMultipleValue(optList, o -> o.hasSameOptions(opt));
}
but that made it A LOT slower.
PS. : its not the complete code, just an example of what im trying to do. I hope it is more understandable this time :)
probably not the most elegant or optimal solution but here is already a quick approach that give the result based on your description. It use the HashMap as proposed in the comment of #Joseph Larson
I went for a set of char to ensure values are not duplicate in it but feel free to adapt :)
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
class Scratch {
public static class Option{
String opt1;
String opt2;
String opt3;
String optResult;
public Option(String opt1, String opt2, String opt3, String optResult) {
this.opt1 = opt1;
this.opt2 = opt2;
this.opt3 = opt3;
this.optResult = optResult;
}
public static String merge(String a, String b){
StringBuilder value = new StringBuilder();
Set<Character> result = new HashSet<>();
for(char c : a.toCharArray()){
result.add(c);
}
for(char c : b.toCharArray()){
result.add(c);
}
for(char c : result){
value.append(c);
}
return value.toString();
}
public Option(Option a, Option b) {
this(merge(a.opt1, b.opt1), merge(a.opt2, b.opt2), merge(a.opt3, b.opt3), merge(a.optResult, b.optResult));
}
String getKey(){
return String.join(":", opt1, opt2, opt3);
}
int distance(Option option){
int diff1 = this.opt1.equals(option.opt1)?0:1;
int diff2 = this.opt2.equals(option.opt2)?0:1;
int diff3 = this.opt3.equals(option.opt3)?0:1;
int diff4 = this.optResult.equals(option.optResult)?0:1;
return diff1 + diff2 + diff3 + diff4;
}
public String toString(){
return getKey();
}
}
public static void main(String[] args) {
Option[] data = new Option[]{
new Option("12", "45", "AB", "12"),
new Option("12", "45", "AB", "3"),
new Option("12", "45", "AB", "4"),
new Option("12", "45", "AC", "1"),
new Option("12", "45", "AC", "12"),
new Option("3", "45", "AC", "13"),
new Option("12", "45", "AD", "12"),
};
mergeExact(data);
mergeClose(data, 1);
}
private static void mergeClose(Scratch.Option[] data, int distance){
Map<Option, Set<Character>> buffer = new HashMap<>();
for(Option option : data) {
boolean found = false;
Option toDelete = null;
for(Map.Entry<Option, Set<Character>> entry : buffer.entrySet()){
if(option.distance(entry.getKey()) <= distance){
Option merged = new Option(entry.getKey(), option);
for(char c : option.optResult.toCharArray()){
entry.getValue().add(c);
}
buffer.put(merged, entry.getValue());
toDelete = entry.getKey();
found = true;
break;
}
}
if(found) {
buffer.remove(toDelete);
}else{
Set<Character> set = new HashSet<>();
for(char c : option.optResult.toCharArray()){
set.add(c);
}
buffer.put(option, set);
}
}
System.out.println(String.format("merge with distance of %d:: %s", distance, buffer));
}
private static void mergeExact(Scratch.Option[] data) {
Map<String, Set<Character>> buffer = new HashMap<>();
for(Option option : data){
Set<Character> item = buffer.computeIfAbsent(option.getKey(), k -> new HashSet<>());
for(char c : option.optResult.toCharArray()){
item.add(c);
}
}
System.out.println("exact merge:: "+buffer);
}
}
output is
exact merge:: {3:45:AC=[1, 3], 12:45:AD=[1, 2], 12:45:AC=[1, 2], 12:45:AB=[1, 2, 3, 4]}
merge with distance of 1:: {12:45:AB=[1, 2, 3, 4], 3:45:AC=[1, 3], 12:45:ACD=[1, 2]}
EDIT: missed a part of the question, updating to add the merge when difference is close. This part is probably even worst that the first one in terms of optimisation but it's a working bases :)
I have 2 Arraylists in my app. First arraylist is of Object type which contains a list of questions. Now this list of questions have a field named "Keywords". This is a String but can contain comma separated keywords.
Now I have a text field where user can search question based on these keywords.Issue that I am facing is that I want to filter out question from the question list according to the number of keyword matches.
For eg. User entered 3 comma separated keywords in the search text field. What I want now is if all 3 keyword matches with some value in the question list then I have to return those elements only. This part is easy and I can do it.
But if we don't get any exact match in the list, then I have to find that item which has the maximum keyword match i.e. if 2 out of 3 keywords from the comma separated String matches from some item in the list, then I have to return that item as result.
Value Stored in List :-
a) Hi, Hello, Hola, Bonjour.
b) Hi, Hello
c) Hi
Value entered in the search text :-
Hi, Hello, Hola
Now in response I want only the first element as it has 3 keywords matching from what user entered.
I am unable to figure out how to do this. Moreover I am fetching this questions list from sqlite database, so if this can be done with some sql queries then I am ready for that thing too.
This is my current code for filter method
public ArrayList<QuestionAnswerModal> filter(String keyword,boolean isQuestionSearch) {
ArrayList<QuestionAnswerModal> arrayList = new ArrayList<>();
if (!isQuestionSearch) {
for (QuestionAnswerModal modal : questionAnswerArrayList) {
if (modal.getKeyword().equalsIgnoreCase(keyword)) {
arrayList.add(modal);
}else{
ArrayList<String> keywords=new ArrayList<>();
String[]word=modal.getKeyword().split(",");
}
}
if (arrayList.size() > 0) {
System.out.print("list size "+arrayList.size());
} else {
System.out.print("No records found");
}
return arrayList;
}else{
for (QuestionAnswerModal modal : questionAnswerArrayList) {
if (modal.getQuestion().equalsIgnoreCase(keyword)) {
arrayList.add(modal);
}
}
if (arrayList.size() > 0) {
System.out.print("list size "+arrayList.size());
} else {
System.out.print("No records found");
}
return arrayList;
}
}
I leave it to you as an exercise to figure out how this solution works, but feel free to ask any questions you wish.
Java 7 solution:
import java.util.*;
import static org.apache.commons.lang3.StringUtils.trimToEmpty;
public class MaxMatchFinder {
public static void main(String[] args) {
Map<String, Set<String>> tagsByName = new HashMap<>();
tagsByName.put("a", new HashSet<>(Arrays.asList("Hi", "Hello", "Hola", "Bonjour")));
tagsByName.put("b", new HashSet<>(Arrays.asList("Hi", "Hello")));
tagsByName.put("c", new HashSet<>(Arrays.asList("Hi")));
String searchText = "Hi, Hello, Hola";
String[] tagsToFind = searchText.split(",");
Map<String, Integer> matchCountsByEntryName = new HashMap<>();
for (String tagToFind : tagsToFind) {
for (String entryName : tagsByName.keySet()) {
Set<String> tags = tagsByName.get(entryName);
if (tags.contains(trimToEmpty(tagToFind))) {
Integer count = matchCountsByEntryName.get(entryName);
Integer incrementedCount = count == null ? 1 : count + 1;
matchCountsByEntryName.put(entryName, incrementedCount);
}
}
}
List<Map.Entry<String, Integer>> sortedEntries = new ArrayList<>(matchCountsByEntryName.entrySet());
Collections.sort(sortedEntries, new Comparator<Map.Entry<String, Integer>>() {
#Override
public int compare(Map.Entry<String, Integer> e1, Map.Entry<String, Integer> e2) {
return e2.getValue().compareTo(e1.getValue());
}
});
Map.Entry<String, Integer> entryWithMostMatches = sortedEntries.get(0);
System.out.printf("Of the entries to be searched," +
" entry \"%s\" contains the most matches (%d).\n",
entryWithMostMatches.getKey(), entryWithMostMatches.getValue());
}
}
Java 8 solution:
import java.util.*;
import java.util.stream.Collectors;
import static org.apache.commons.lang3.StringUtils.trimToEmpty;
public class MaxMatchFinder {
public static void main(String[] args) {
Map<String, Set<String>> tagsByName = new HashMap<>();
tagsByName.put("a", new HashSet<>(Arrays.asList("Hi", "Hello", "Hola", "Bonjour")));
tagsByName.put("b", new HashSet<>(Arrays.asList("Hi", "Hello")));
tagsByName.put("c", new HashSet<>(Arrays.asList("Hi")));
String searchText = "Hi, Hello, Hola";
String[] tagsToFind = searchText.split(",");
Map<String, Integer> matchCountsByEntryName = new HashMap<>();
Arrays.stream(tagsToFind)
.forEach(tagToFind -> {
for (String entryName : tagsByName.keySet()) {
Set<String> tags = tagsByName.get(entryName);
if (tags.contains(trimToEmpty(tagToFind))) {
matchCountsByEntryName.compute(entryName, (k, v) -> v == null ? 1 : v + 1);
}
}
});
List<Map.Entry<String, Integer>> sortedEntries = matchCountsByEntryName.entrySet().stream()
.sorted((e1, e2) -> e2.getValue().compareTo(e1.getValue()))
.collect(Collectors.toList());
Map.Entry<String, Integer> entryWithMostMatches = sortedEntries.get(0);
System.out.printf("Of the entries to be searched," +
" entry \"%s\" contains the most matches (%d).\n",
entryWithMostMatches.getKey(), entryWithMostMatches.getValue());
}
}
After many days of trying, I think I found solution to my problem. Below is the code I am using now.
public ArrayList<QuestionAnswerModal> filter(String keyword, boolean isQuestionSearch) {
ArrayList<QuestionAnswerModal> arrayList = new ArrayList<>();
HashMap<String, Integer> countList = new HashMap<>();
if (isQuestionSearch) {
for (QuestionAnswerModal modal : questionAnswerArrayList) {
if (modal.getKeyword().equalsIgnoreCase(keyword)) {
arrayList.add(modal);
}
}
return arrayList;
} else {
//will store the index of the question with largest match
int[] count = new int[questionAnswerArrayList.size()];
for (int i = 0; i < questionAnswerArrayList.size(); i++) {
List<String> keywords = new ArrayList<>();
String[] word = questionAnswerArrayList.get(i).getKeyword().split(",");
keywords = Arrays.asList(word);
String[] userKeywords = keyword.split(",");
for (int j = 0; j < userKeywords.length; j++) {
if (keywords.contains(userKeywords[j])) {
if (countList.size() == 0) {
//countList.put(userKeywords[j], 1);
count[i]++;
}
}
}
}
//index with largest match
int largest = 0;
//valu if the index
int largestCount = count[largest];
for (int i = 0; i < count.length; i++) {
if (count[i] > largestCount)
largest = i;
}
arrayList.add(questionAnswerArrayList.get(largest));
if (arrayList.size() > 0) {
lvQuestionAnswer.invalidate();
QuestionAnswerAdapter questionAnswerAdapter = new QuestionAnswerAdapter(arrayList, MainActivity.this, MainActivity.this, MainActivity.this);
lvQuestionAnswer.setAdapter(questionAnswerAdapter);
dialog.dismiss();
} else {
Toast.makeText(MainActivity.this, "No records found", Toast.LENGTH_SHORT).show();
}
return arrayList;
}
}
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
i have multiple arraylist like this:
arraylist
arrayList.add(product1);
arrayList.add(product2);
arrayList.add(product3);
arrayList.add(product4);
.
.
.
.
arrayList.add(productn);
arraylist2
arrayList2.add(name1);
arrayList2.add(name2);
arrayList2.add(name3);
arrayList2.add(name4);
.
.
.
arrayList2.add(namen);
arraylist3
arrayList3.add(id1);
arrayList3.add(id2);
arrayList3.add(id3);
arrayList3.add(id4);
.
.
.
arrayList3.add(idn);
i want to create string of array combine of arraylists above
with index of string in arraylist
so something like this
string[1] = {product1,name1,id1 }
string[2] = {product2,name2,id2 }
.
.
.
string[n] = {productn,namen,idn }
any idea how to do it?
sorry before
and thanks in advance
Make a class and then an array of instances/objects of that class. Here's an example,
public class Product{
String name;
String id;
public Product(String name, String id){ //constructor for the object
this.name = name;
this.id = id;
}
}
Then in your main method, create an array of type Product and added instances of Product to the array,
Product[] products = new Product[10];
products[0] = new Product("cheese", "0");
System.out.println(products[0].name + " " + products[0].id);
You can adjust to your liking, for example you can edit the Product class by adding more instance fields other than name and id, resize the array, change the array to an arraylist, etc..
Do you mean something like that?
int size = 10;
List<String> arr1 = new ArrayList<>();
List<String> arr2 = new ArrayList<>();
List<String> arr3 = new ArrayList<>();
String[] string = new String[size];
for (int i = 0; i < size; i++) {
string[i] = arr1.get(i) + arr2.get(i) + arr3.get(i);
}
You can loop through them in one loop and create an object with it.
we need to create a class
// The data type will change based on the data type you have them as
public class MyObject {
private Product product;
private Name name;
private Id id;
public MyObject(Product p, Name n, Id i) {
product = p;
name = n;
id = i;
}
// All Getters & toString()
}
Now for the loop :
List< MyObject> myList = new ArrayList < MyObject >();
for ( int i=0 ; i < arrayList || i < arrayList2 || i < arrayList3 ) {
myList.add(new MyObject(arrayList.get(i),arrayList2.get(i),arrayList3.get(i)))
}
Note you can override the toString method in you class to get the output in the way you want.
EG:
public String toString() {
return "Name: '" + this.name + "', ID: '" + this.id + "', Product: '" + this.product + "'";
}
public static void main(String[] args) {
List<String> arrayList = new ArrayList<>();
arrayList.add("product1");
arrayList.add("product2");
arrayList.add("product3");
List<String> arrayList2 = new ArrayList<>();
arrayList2.add("name1");
arrayList2.add("name2");
arrayList2.add("name3");
List<String> arrayList3 = new ArrayList<>();
arrayList3.add("id1");
arrayList3.add("id2");
arrayList3.add("id3");
int n = arrayList.size();
List<String[]> productlist = new ArrayList<>();
for(int i = 0; i< n;i++){
productlist.add(new String[]{arrayList.get(i),arrayList2.get(i),arrayList3.get(i)});
System.out.println(Arrays.toString(productlist.get(i)));
}
}
The following code separates the duplicate names into 1 column and sum of numbers associated with the names into the second column.
Like :
Nokia 21
Blackberry 3
Nimbus 30
from the array given in the program.
I want to know the final length of the array that contain these entries. In this case 3. How do i calculate that ?
package keylogger;
import java.util.ArrayList;
import java.util.List;
public class ArrayTester {
private static int finalLength = 0;
private static String Name[][];
private static String data[][] = {
{"Nokia" , "7"},
{"Blackberry" ,"1"},
{"Nimbus","10"},
{"Nokia" , "7"},
{"Blackberry" , "1"},
{"Nimbus","10"},
{"Nokia" , "7"},
{"Blackberry" , "1"},
{"Nimbus","10"}
};
public void calculator() {
Name = new String[data.length][2];
List<String> marked = new ArrayList<String>();
try {
for(int i=0;i<data.length;i++) {
Name[i][0] = data[i][0];
Name[i][1] = data[i][1];
String name = data[i][0];
if(marked.contains(name)) {
continue;
}
marked.add(name);
int k = i + 1;
int v = k;
for (int j = 0; j < data.length - v; j++) {
String s = data[k][0];
if(Name[i][0].equalsIgnoreCase(s)) {
Name[i][0] = s;
Integer z = Integer.parseInt(Name[i][1]) + Integer.parseInt(data[k][1]);
Name[i][1] = z.toString();
}
k++;
}
}
}catch(Exception exc) {
exc.printStackTrace();
}
}
public static void main(String args[]) {
ArrayTester o = new ArrayTester();
o.calculator();
for(String s[] : Name) {
for(String x : s) {
System.out.println(x);
}
}
}
}
As usual, the "problem" is poor coding. Your entire program, properly written, can be reduced to just 3 lines of code (5 if you include defining the array and printing the output):
public static void main(String[] args) {
String data[][] = {{"Nokia", "7"}, {"Blackberry", "1"}, {"Nimbus", "10"},
{"Nokia", "7"}, {"Blackberry", "1"}, {"Nimbus", "10"}, {"Nokia", "7"},
{"Blackberry", "1"}, {"Nimbus", "10"}, {"Zebra", "78"}};
HashMap<String, Integer> totals = new HashMap<String, Integer>();
for (String[] datum : data)
totals.put(datum[0], new Integer(datum[1]) + (totals.containsKey(datum[0]) ? totals.get(datum[0]) : 0));
System.out.println("There are " + totals.size() + " brands: " + totals);
}
Output:
There are 4 brands: {Nimbus=30, Zebra=78, Nokia=21, Blackberry=3}
You can't know it a priori, the size will be known just when you'll have finished splitting the strings and doing your math.
In your example in the end marked.size() will have the size you are looking for but I'd suggest you to directly use a HashMap so that you won't care about searching for existing elements in linear time and then convert it to an array.
Something like:
String[][] names = new String[map.size()];
Set<String> keys = map.keys();
int c = 0;
for (String k : keys)
{
names[c] = new String[2];
names[c][0] = k;
names[c++][1] = map.get(k).toString();
}
As far as I understand it, you want to know the number of distinct names in your array without calling calculator(), right? I don't really know if that makes sense as you still have to go through every entry and compare it with a set. But you could do it with a Set:
private int getNumberOfEntries(String[][] data) {
Set<String> names = new HashSet<String>();
for (int i=0; i<data.length; i++) {
names.add(data[i][1]);
}
return names.size();
}
Now you can just call int n = getNumberOfEntries(data);...
EDIT: Of course it makes more sense to do the sums in the same step, see Bohemians solution for that.