I have an arraylist called fetchContactName() which returns all names (31) in my contact list, an arraylist called fetchContactNumbers() which returns all phone numbers (31) associated with fetchContactName(), and an arraylist called newList which has all the numbers that sent me text messages (6).
I was trying to change the phone numbers in newList by looking for the same numbers in fetchContactNumbers(). When there was a match, I would then index the position in fetchContactNumbers() and use that index to get the name at the same position in fetchContactName(). From there, I would replace the numbers in newList with the names in fetchContactName() according to the indexed position.
This is an example I've made that executes as stated above:
http://pastebin.com/pApHNkXa
The problem with the above example is that when I apply it to my listview, only one element in the list is changed to a name. More oddly, newList.get(3) is the only one that changed to a name. Not newList at positions 0, 1, 2, 4 and 5.
From others suggests, how can I use a HashMap to give the same expected result as the example given above? I was told to use fetchContactNumbers() and fetchContactNames() in the Hashmap then use the HashMap to compare with newList, but I cant find any source to achieve this.
UPDATE:
Here is the working code for my HashMap, but the results are still the same as above:
for (String str : fetchContactNames()) {
contactNameNew += str + " ";
}
for (String str2 : fetchContactNumbers()) {
contactNumberNew += str2 + " ";
}
//String to split
String temp[];
String temp2[];
String delimiter = " ";
temp = contactNameNew.split(delimiter);
temp2 = contactNumberNew.split(delimiter);
HashMap<String, String> contacts = new HashMap<String, String>();
contacts.put(contactNameNew, contactNumberNew);
for(int i = 0; i < fetchContactNames().size(); i++){
contacts.put(temp[i], temp2[i]);
}
Iterator<Entry<String, String>> iterator = contacts.entrySet().iterator();
while(iterator.hasNext()){
Entry<String, String> entry = iterator.next();
int position = getPosition(newlist, entry.getValue());
if (newlist.contains(entry.getValue())) {
newlist.set(position, entry.getKey());
}
}
I think it will be better if I changed your code and answered...
import java.util.ArrayList;
import java.util.HashMap;
public class StringT {
public static void main(String[] args) {
// alpha would represent fetchContactNames()
ArrayList<String> alpha = new ArrayList<String>();
// bravo would represent fetchContactNumbers()
HashMap<String, String> bravo = new HashMap<String, String>();
// charlie would represent newList
ArrayList<String> charlie = new ArrayList<String>();
bravo.put("1", "One"); charlie.add("5");
bravo.put("2", "Two"); charlie.add("1");
bravo.put("3", "Three"); charlie.add("3");
bravo.put("4", "Four"); charlie.add("4");
bravo.put("5", "Five"); charlie.add("2");
// this will print charlie just as you see above
for(int i = 0; i < charlie.size(); i ++){
System.out.println(charlie.get(i));
}
System.out.println("---------------------");
// this will print charlie with the numbers replaced as names
for(int i = 0; i < charlie.size(); i++){
String value;
if((value = bravo.get(charlie.get(i))) != null){
charlie.set(i, value);
}
}
for(int i = 0; i < charlie.size(); i ++){
System.out.println(charlie.get(i));
}
}
}
your code is working that u placed here http://pastebin.com/pApHNkXa i tried it in android and its working alright its giving output as five, two, seven, three .
Related
I have to create a HashMap that records the letters in a string and their index values in a ArrayList, so that if the HashMap is called with some string key, each related index integer is returned, and so that the map can be called by itself such that each key is shown with their indexes, For example for the string "Hello World", the map would look something like:
d=[9], o=[4, 6], r=[7], W=[5], H=[0], l=[2, 3, 8], e=[1].
I'm really confused by the requirement of the inputs as String and ArrayList, rather than chars and integers. Could you explain to me the relationship of the map to those objects, and to their components which are ultimately what are recorded as keys and values? When trying to debug, it stops processing before the map call.
The error message is:
java.lang.AssertionError: Wrong number of entries in Concordance. Expected: 5. Got: 1
Expected :1
Actual :5
But I really think I'm not grasping HashMap very well, so I'd appreciate if anyone could guide me through the basics, or provide anything educational about using HashMap, especially ones that use ArrayList.
public HashMap<String, ArrayList<Integer>> concordanceForString(String s) {
HashMap<String, ArrayList<Integer>> sMap = new HashMap<>();//create map "sMap"
char[] sArray = new char[s.length()]; //create character array, "sArray", for string conversion
ArrayList<Integer> sCharIndex = new ArrayList<Integer>();
for (int i = 0; i < s.length(); i++) {
sArray[i] = s.charAt(i); // convert string into array
}
for (int j = 0; j < sArray.length; j++){
sCharIndex.add(j); // add char indexes to index ArrayList
}
sMap.put(s, sCharIndex); //add the String and ArrayList
return sMap; // I feel like this should be sMap.get(s) but when I do, it gives me the zigzag red underline.
}
Here is a way to do it:
String input = "hello world";
Map<String, List<Integer>> letters = new HashMap<String, List<Integer>>();
// remove all whitespace characters - since it appears you are doing that
String string = input.replaceAll("\\s", "");
// loop over the length of the string
for (int i = 0; i < string.length(); i++) {
// add the entry to the map
// if it does not exist, then a new List with value of i is added
// if the key does exist, then the new List of i is added to the
// existing List
letters.merge(string.substring(i, i + 1),
Arrays.asList(i),
(o, n) -> Stream.concat(o.stream(), n.stream()).collect(Collectors.toList()));
}
System.out.println(letters);
that gives this output:
{r=[7], d=[9], e=[1], w=[5], h=[0], l=[2, 3, 8], o=[4, 6]}
EDIT - this uses a Character as the key to the map:
String input = "hello world";
Map<Character, List<Integer>> letters = new HashMap<Character, List<Integer>>();
String string = input.replaceAll("\\s", "");
for (int i = 0; i < string.length(); i++) {
letters.merge(string.charAt(i), Arrays.asList(i), (o, n) ->
Stream.concat(o.stream(), n.stream()).collect(Collectors.toList()));
}
System.out.println(letters);
Essentially, this is what you want to do.
This presumes a HashMap<String, List<Integer>>
List<Integer> sCharIndex;
for (int i = 0; i < s.length(); i++) {
// get the character
char ch = s.charAt(i);
if (!Character.isLetter(ch)) {
// only check letters
continue;
}
ch = ch+""; // to string
// get the list for character
sCharIndex = sMap.get(ch);
// if it is null, create one and add it
if (sCharIndex == null) {
// create list
sCharIndex = new ArrayList<>();
// put list in map
sMap.put(ch, sCharIndex);
}
// at this point you have the list so
// add the index to it.
sCharIndex.add(i);
}
return sMap;
A hashMap is nothing more than a special data structure that takes an object as a key. Think of an array that takes a digit as an index and you can store anything there.
A hashMap can take anything as a key (like an index but it is called a key) and it can also store anything.
Note that your key to hashMap is a String but you're using a character which is not the same. So you need to decide which you want.
HashMap<String, List<Integer>> or HashMap<Character, List<Integer>>
There are also easier ways to do this but this is how most would accomplish this prior to Java 8.
Here is a much more compact way using streams. No loops required.
Map<String, List<Integer>> map2 = IntStream
.range(0,s.length())
// only look for letters.
.filter(i->Character.isLetter(s.charAt(i)))
.boxed()
// stream the Integers from 0 to length
// and group them by character in a list of indices.
.collect(Collectors.groupingBy(i->s.charAt(i)+""));
But I recommend you become familiar with the basics before delving into streams (or until your instructor recommends to do so).
For more information check out The Java Tutorials
Check out this code :
public static void main(String []args){
//Create map of respective keys and values
HashMap<Character, ArrayList<Integer>> map = new HashMap();
String str = "Hello world"; //test string
int length = str.length(); //length of string
for(int i = 0; i < length; i++){
ArrayList<Integer> indexes = new ArrayList(); //empty list of indexes
//character of test string at particular position
Character ch = str.charAt(i);
//if key is already present in the map, then add the previous index associated with the character to the indexes list
if(map.containsKey(ch)){
//adding previous indexes to the list
indexes.addAll(map.get(ch));
}
//add the current index of the character to the respective key in map
indexes.add(i);
//put the indexes in the map and map it to the current character
map.put(ch, indexes);
}
//print the indexes of 'l' character
System.out.print(map.get('l'));
}
The code is self explanatory.
public class Array {
public static void main(String[] args) {
printSortedMap(concordanceForString("Hello world")); // r[7] d[9] e[1] w[5] H[0] l[2, 3, 8] o[4, 6]
}
public static HashMap<String, ArrayList<Integer>> concordanceForString(String s) {
HashMap<String, ArrayList<Integer>> sMap = new HashMap<>();
String str = s.replace(" ", "");
for (int i = 0; i < str.length(); i++) {
ArrayList<Integer> sCharIndex = new ArrayList<Integer>();
for (int j = 0; j < str.length(); j++) {
if ( str.charAt(i) == str.charAt(j) ) {
sCharIndex.add(j);
}
}
sMap.put(str.substring(i,i+1), sCharIndex);
}
return sMap;
}
public static void printSortedMap(HashMap<String, ArrayList<Integer>> sMap) {
for (Map.Entry<String, ArrayList<Integer>> entry : sMap.entrySet()) {
System.out.println(entry.getKey() + entry.getValue());
}
}
I wrote a program in Java where it retrieves records from a database table and stored them in a hashmap.
The keys and values of them are like the following:
Key(represent words) Values(represent filename)
w1 file1
w2 file1
w3 file2
w4 file1
w5 file2
w6 file1,file2
............
The list goes on and on but this is just an idea of how it looks like.As you can see, there's no duplicate for words and they are unique.
Given that I have this hashmap info,I need to find the intersection of the key and it's next key and return the results of the intersection. The idea looks like this:
w1∩w2= file1
w2∩w3= empty
w3∩w4= empty
........and it keeps going until it reaches the finishes the final pair of keys in the hashmap.
Since the pair of intersection results depends on the number of keys in the hashmap,I am guessing I'll need to use some loop to keep it iterating to return all the results.
Is there a way on how to get the intersection of each subsequent keys and also a way that is optimize regardless the size of the hashmap?
I appreciate any suggestion.
Make a variable that will hold all those intersections. In your loop retrieve 2 keys at a time. Compare each values of the 2 keys and if they are the same add the value to your intersection holder. Repeat the steps until there is no more pairs.
Here is the code.
Add this below your try/catch
LinkedHashmap<String, Set<String>> intersectionMap = new LinkedHashmap<>();
if (map.keySet() != null) {
String[] keys = map.keySet().toArray(new String[map.keySet().size()]);
for (int i = 0; i < keys.length - 1; i++) {
String key1 = keys[i];
String key2 = keys[i + 1];
TreeSet<String> interSection = intersection(map.get(key1), map.get(key2));
intersectionMap.put(key1 + "∩" + key2, interSection);
}
}
Add this helper method. This method will find the intersection of the two sets. This will be the key in solving your problem.
public static TreeSet<String> intersection(TreeSet<String> setA, TreeSet<String> setB) {
// An optimization to iterate over the smaller set
if (setA.size() > setB.size()) {
return intersection(setB, setA);
}
TreeSet<String> results = new TreeSet<>();
for (String element : setA) {
if (setB.contains(element)) {
results.add(element);
}
}
return results;
}
Yet another version with set operations:
Map<String>, Set<String>> intersections(Map<String, TreeSet<String>> map) {
Map<String>, Set<String>> result = new TreeMap<>();
List<String> words = new ArrayList<>(map.keySet());
words.sort();
for (int i = 0; i < words.size() - 1; ++i) {
String wordI = words.get(i);
Set<String> valueI = map.get(wordI);
for (int j = i + 1, j < words.size(); ++j) {
String wordJ = words.get(j);
Set<String> valueJ = map.get(wordJ);
String word = wordi + "∩" + words[j];
Set<String> value = new TreeSet<>(valueI);
value.retainAll(valueJ);
result.put(word, value);
}
}
return result;
}
I currently have this code:
String foxes = "The,Quick,Brown,Fox,Jumped,Over,The,Lazy,Dog.";
System.out.println(" Here is the string unedited: " + foxes);
String lowerCase = foxes.toLowerCase() .replaceAll("[\.:;'\"!\?]", " ");
System.out.println(" Here is the string (no caps + no punctuation): " + lowerCase);
List<String> foxesList = new ArrayList<String>(Arrays.asList(lowerCase.split(",")));
In short this code creates a String, makes it non case sensitive and then converts it into an array.
I now need to find the positions of each of the duplicates in the array and I currently am aware that it has something to do with nested loops. The duplicates are The which occurs 2 times. I need to know the positions of these 2 duplicates.
You can use HashMap<String, int[]:
Map<String, ArrayList<Integer>> map = new HashMap<>();
for (int i = 0; i < foxesList.size(); i++) {
String fox = foxesList.get(i);
ArrayList<Integer> list = map.get(fox);
if (list == null) {
list = new ArrayList<>();
list.add(i);
map.put(fox, list);
} else {
list.add(i);
}
}
In this map for each fox name, you'll store all indexes of this fox. In case the list has more then one element, it means there is a duplicate.
Algo to find index of duplicate
Create an array of string ( by spliting input by " ")
Iterate over array and build a map of each array element to list of its position in the map.
3.Finally you have all info in map. For every entry you have index it occur. If it is more than 1 then it is duplicate and u have index
You can use :
HashMap(key: String, value: ArrayList)
to store the strings
where arraylist will store the corresponding indexes.
If value.size() > 1, it's keys occurrence > 1.
Code :
HashMap<String, ArrayList<Integer>> dictMap = new HashMap<String, ArrayList<Integer>>();
String strArr[]={"Hi", "Foo", "Bar", "Foo"};
for(int i = 0; i < strArr.length; i++){
String str = strArr[i];
if(dictMap.containsKey(str)){
ArrayList<Integer> al = dictMap.get(str);
al.add(i);
}
else{
ArrayList<Integer> al = new ArrayList<Integer>();
al.add(i);
dictMap.put(str, al);
}
}
There are already a few correct answers here, let me just give a slightly more concise one to create the map, assuming that you are using Java 8:
Map<String, List<Integer>> map = new HashMap<>();
for (int i = 0; i < foxesList.size(); i++) {
String fox = foxesList.get(i);
map.computeIfAbsent(fox, f -> new ArrayList<>()).add(i);
}
Using Map#computeIfAbsent allows to have just one line for both the case where you already have a list in the map and where you don't.
I have an arrayList of String which I would like to display in a Spinner or drop down menu, but mostly what happens is I have Strings repeating, what I want to do is to search through the arrayList for similarities, if its found a string for example "Hello World" occurs 7 times in the arrayList, remove the the other 6 and assign 7 to it to show that it occurred 7 times, so my new String will be "Hello world (7)", could anyone help me on how I can implement this in my code below:
for(int i = 0; i < timesCalleddb.getAllTimesCalled(missedCall.getNumber()).size(); i++)
{
if(timesCalleddb.getAllTimesCalled(missedCall.getNumber()).get(i) ==
timesCalleddb.getAllTimesCalled(missedCall.getNumber()).get(i+1))
{
//where am guessing the implementation my problem should be
}
}
You should consider using map data structure, since you have to store the counter, otherwise, hash set would be perfect:
ArrayList<String> strs = ...;
HashMap<String, Integer> counter = new HashMap<String, Integer>();
for(String s : strs) {
counter.put(s, counter.get(s) == null ? 1 : counter.get(s) + 1);
}
for(String s : counter.keySet()) {
System.out.println(s + " (" + counter.get(s) + ")");
}
You could do the following:
Iterate over the List and make a HashMap<String, Integer> indicating how many times each String appears.
Remove duplicates from the List using list = new ArrayList<String>(new LinkedHashSet<String>(list));. Using a LinkedHashSet means that the order is kept.
Build up a new List by iterating over the List and adding either string or string + " (" + map.get(string) + ")" depending on whether map.get(string) is 1 or more than 1.
You can use this code for filtering you CustomList based on a particular String of the list. If you want to count the number of occurence, you can add some counter in the loop.
List<MyCustomObject> arrayList = new ArrayList<>();
List<MyCustomObject> result = new ArrayList<>();
Set<String> set = new HashSet<>();
for(MyCustomObject item : arrayList) {
if(set.add(item.getSomeString()) {
resultArray.add(item);
}
}
arrayList.clear();
arrayList.addAll(result);
To remove the repeated String from a List, use the following:
List<String> arrayList = new ArrayList<>();
// Your elements must be added to the arrayList, before progressing to the next step.
Set<String> set = new HashSet<>();
set.addAll(arrayList );
// Code for getting count of each String
int count = 0;
List<Integer> arrayListCount = new ArrayList<>();
for (Iterator<String> it = set.iterator(); it.hasNext(); ) {
String str = it.next();
arrayListCount.add(count , 0);
for(int i = 0; i < arrayList.size(); i++){
String s = arrayList.get(i);
if (str.equals(s)) {
arrayListCount.set(count , arrayListCount.get(count) + 1);
}
}
count++;
}
// Code for getting count ends here
arrayList.clear();
arrayList.addAll(set);
Note: The sequence of the List won't be retained.
Hope that Helps!!!
I want to get the smallest match of strings in the list. Though I'm successful doing so but the problem is i want to count that how many match counts have been made so:
List<String> mylist=new LinkedList<String>();
Set<String> result=new LinkedHashSet<String>();
mylist.add("interpreter");
mylist.add("interprete");
mylist.add("interpret");
mylist.add("developed");
mylist.add("develops");
mylist.add("develop");
mylist.add("interpret");
String small="";
Collections.sort(mylist);
Collections.reverse(mylist);
for(int i=0;i<mylist.size();i++)
{
small=mylist.get(i);
for(int j=i;j<mylist.size();j++)
{
if(small.contains(mylist.get(j)))
{
small=mylist.get(j);
}
}
result.add(small);
}
for (String string : result) {
System.out.println(string);
}
So that the output should be:
interpret=4
develop=4
Problem occurs with the following code i am trying:
List<String> mylist=new LinkedList<String>();
Set<String> result=new LinkedHashSet<String>();
mylist.add("interpreter");
mylist.add("interprete");
mylist.add("interpret");
mylist.add("developed");
mylist.add("develops");
mylist.add("develop");
mylist.add("interpret");
mylist.add("crawler");
mylist.add("crawl");
mylist.add("mobile");
mylist.add("mob");
mylist.add("juni");
mylist.add("junis");
Collections.sort(mylist);
Collections.reverse(mylist);
String small="";
int c=0;
for(int i=0;i<mylist.size();i++)
{
c+=1;
small=mylist.get(i);
for(int j=i;j<mylist.size();j++)
{
if(small.contains(mylist.get(j)))
{
small=mylist.get(j);
c+=1;
}
}
result.add(small);
}
for (String string : result) {
System.out.println(string+"="+c);
}
can somebody help me please!
Putting #jambriz's answer in your code:
1.Use a HashMap
HashMap<String, Integer> result= new LinkedHashMap<String, Integer>();
2.Instead of result.add(small); now, add the value in hashmap only if the value is new or the count is less than the previous count. Also, set c=0 here
if (!result.containsKey(small) || result.get(small) < c)
result.put(small, c);
c = 0;
3.At Last print your results:
for (String key : result.keySet())
System.out.println(key + ": " + result.get(key));
ok, first of all, your first code would print
interpret
develop
because you aren´t counting anything
and it should be
interpret=4
develop=3
anyway.
The second block only has one counter 'c'. You should have one counter per each found word.
I would suggest using a Map of Strings and Integers. When the String is nonexistent you put(small,1) and when it exists you get the Integer and add one to it.
Let us know if that worked
(btw, there's no regex in your code, it shouldn't be tagged as such)
String[] smallestStrings; //this has "interpret", "develop"
int[] matches = new int[smallestStrings.length];
for (int i = 0; i < matches.length; i++) {
matches[i] = 0;
for (String s : mylist) if (s.contains(smallestStrings[i])) matches[i]++;
}