How to search for similarities in an ArrayList - java

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!!!

Related

How to get the positions of array duplicates JAVA

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.

Counting occurrences in a string array and deleting the repeats using java

i'm having trouble with a code. I have read words from a text file into a String array, removed the periods and commas. Now i need to check the number of occurrences of each word. I managed to do that as well. However, my output contains all the words in the file, and the occurrences.
Like this:
the 2
birds 2
are 1
going 2
north 2
north 2
Here is my code:
public static String counter(String[] wordList)
{
//String[] noRepeatString = null ;
//int[] countArr = null ;
for (int i = 0; i < wordList.length; i++)
{
int count = 1;
for(int j = 0; j < wordList.length; j++)
{
if(i != j) //to avoid comparing itself
{
if (wordList[i].compareTo(wordList[j]) == 0)
{
count++;
//noRepeatString[i] = wordList[i];
//countArr[i] = count;
}
}
}
System.out.println (wordList[i] + " " + count);
}
return null;
I need to figure out 1) to get the count value into an array.. 2) to delete the repetitions.
As seen in the commenting, i tried to use a countArr[] and a noRepeatString[], in hopes of doing that.. but i had a NullPointerException.
Any thought on this matter will be much appreciated :)
I would first convert the array into a list because they are easier to operate on than arrays.
List<String> list = Arrays.asList(wordsList);
Then you should create a copy of that list (you'll se in a second why):
ArrayList<String> listTwo = new ArrayList<String>(list);
Now you remove all the duplicates in the second list:
HashSet hs = new HashSet();
hs.addAll(listTwo);
listTwo.clear();
listTwo.addAll(hs);
Then you loop through the second list and get the frequency of that word in the first list. But first you should create another arrayList to store the results:
ArrayList<String> results = new ArrayList<String>;
for(String word : listTwo){
int count = Collections.frequency(list, word);
String result = word +": " count;
results.add(result);
}
Finally you can output the results list:
for(String freq : results){
System.out.println(freq);}
I have not tested this code (can't do that right now). Please ask if there is a problem or it doesnÄt work. See these questions for reference:
How do I remove repeated elements from ArrayList?
One-liner to count number of occurrences of String in a String[] in Java?
How do I clone a generic List in Java?
some syntax issues in your code but works fine
ArrayList<String> results = new ArrayList<String>();
for(String word : listTwo){
int count = Collections.frequency(list, word);
String result = word +": "+ count;
results.add(result);
}

Using Java's built-in Set classes to count EACH(keyword) unique element in List values from a list

Given a list that could contain duplicates (like the one below), I need to be able to count Each(keyword) number of unique elements.
List<String> list = new ArrayList<String>();
Set<String> set = new HashSet<String>();
list.add("M1");
list.add("M1");
list.add("M2");
list.add("M3");
set.addAll(list);
System.out.println(set.size());
How do I get the count each unique element from the List?
That means i want to know how many "M1" contains in List(list), how many "M2", etc.
The result should be the following:
2 M1
1 M2
1 M3
You are looking for Map<String, Integer> data structure, not Set
Something like
for(iterating over something){
Integer count =map.get(value);
if( count == null){
map.put(value, 1);
} else{
count++;
map.put(value, count);
}
}
Map is the data structure that maps unique to value
I think you are looking for something like this (I didn't compile it, but it should get you going in the right direction):
List<String> list = ArrayList<>();
Map<String, Integer> counts = new HashMap<>();
// Fill list with values....
for (String item:list) {
Integer count = counts.get(item);
if (count == null) {
// This is the first time we have seen item, so the count should be one.
count = 1;
} else {
// Increment the count by one.
count = count + 1;
}
counts.put(item, count);
}
// Print them all out.
for (Entry<String, Integer> entry : counts.entrySet()) {
System.out.println(entry.getValue() + " " + entry.getKey());
}
Set won't help you in this case, you need a Map:
List<String> list = new ArrayList<String>();
Set<String> set = new HashSet<String>();
list.add("M1");
list.add("M1");
list.add("M2");
list.add("M3");
// ...
Map<String, Integer> counts = new HashMap<String, Integer>();
for(String element: list) {
int currentCount;
if(counts.contains(element)) {
currentCount = counts.get(element) + 1;
} else {
currentCount = 1;
}
counts.put(element, currentCount);
}
// ...
for(String element: counts.keySet()) {
System.out.println("element: " + element + ", times appeared: " + counts.get(element));
}
means You want to know how many "M1" contains in List(list), how many "M2", instead of using set interface, you can use the Map interface because Map contain the key, value pair format ,i.e. Map data structure.
Map<key,Value>
Much easier way: use Collections.frequency()
System.out.println("M2: "+Collections.frequency(list,"M2");
will output
M2: 1

How do I compare 2 arraylists in a Hashmap?

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 .

Java:how to group similar strings (items) to respective array (group)?

I have the following string "0#Aitem, 0#Aitem2, 0#Aitem3, 1#Bitem, 1#Bitem2, 2#Citem, Nitem, Nitem2".
the 0# shows group number. so Aitem, Aitem2, Aitem3 will belong to group 0. Bitem, Bitem2 in group 1. Citem in group 2. If there is no group number, they will all be place in separate group. So Nitem, Nitem2 will be placed in group 3.
I would like to create an array for each group, and place the "items" in respective group(array). So I would end up with something like
[array("Aitem,Aitem2,Aitem3"), array("Bitem, Bitem2"), array("Citem"), array("Nitem, Nitem2")]
I am guessing I need an arrayList to hold all the groups (arrays) which respectively has appropriate elements (items).
This is what I started with but I don't know if this is the best approach. The string is dynamic, so there can be any number of groups and has to follow the criteria above.
String[] x = Pattern.compile(",").split("0#item, 0#item2, 0#item3, 1#item, 1#item2, 2#item, item");
for (int ii=0; ii<x.length; ii++) {
System.out.println(i + " \"" + x[ii] + "\"");
}
My answer shows how you can use a single regex to extract both the group and the item. You can then store these in a map.
String s = "0#Aitem, 0#Aitem2, 0#Aitem3, 1#Bitem, 1#Bitem2, 2#Citem, Nitem, Nitem2";
Pattern p = Pattern.compile("(\\d*)[#]{0,1}(\\w+?)(,|$)");
Matcher m = p.matcher(s);
Map<String, List<String>> map = new TreeMap<String, List<String>>();
while(m.find()){
String group = m.group(1);
String item = m.group(2);
List<String> items = map.get(group);
if(items == null){
items = new ArrayList<String>();
map.put(group, items);
}
items.add(item);
}
//let's print it out
for(String key : map.keySet()){
System.out.println(key + " : " + map.get(key));
}
prints:
: [Nitem, Nitem2]
0 : [Aitem, Aitem2, Aitem3]
1 : [Bitem, Bitem2]
2 : [Citem]
At the moment, items with no group are keyed against an empty string. I'll leave it at as an exercise for you to handle this scenario. It should simply be a case of finding the max key and incrementing it.
I'm sure the regex can be improved too as it was written in haste.
//Create a map for storing groups
Map<String, Collection<String>> groupMap = new HashMap<String, Collection<String>>();
String[] parts = yourString.split("[, ]+"); //Split by each word
for (String part : parts) { //Go over all words
String[] subparts = part.split("#"); //Split to index and value
String groupKey;
String value;
if (subparts.length == 1) { //There is no '#' sign
groupKey = null;
value = subparts[0];
} else if (subparts.length == 2) { //There is one '#'sign
groupKey = subparts[0];
value = subparts[1];
} else {
throw new IllegalArgumentException("Can not parse string");
}
Collection<String> groupContents = groupMap.get(groupKey); //Extract list of items in this group
if (groupContents == null) { //If there was no such group yet - create one
groupMap.put(groupKey, groupContents = new ArrayList<String>());
}
groupContents.add(value); //Add item to group
}
HashMap<String,List<String> myItems = new HashMap<String,List<String>);
Then you can whatever class you want with an sting alias and store as many items as you whish.
You are on right way but I'd like to correct you a little bit.
Use the following regex to split: str.split("\\s*,\\s*"). This will support all possible spaces.
When you get separate item you have to split it again: item.split("#").
To store all this create data structure like List<List<String>>. Then do the following:
String[] parts = item.split("#");
int group = Integer.parseInt(parts[0]);
String itemName = parts[1];
List<String> groupList = allGroups.get(group);
if (groupList == null) {
groupList = new ArrayList<String>();
allGroups[group] = groupList;
}
groupList.add(itemName);
I am sorry if the code sample contains syntax errors. It is written here, on the site and should just help you to see the idea.
Another solution based on Maps.
System.out.println("###Parsing results and populating map");
String[] x = Pattern.compile("\\s*,\\s*").split(
"0#item, 0#item2, 0#item3, 1#item, 1#item2, 2#item, item");
Map<String, List<String>> result = new TreeMap<String, List<String>>();
for (int i = 0; i < x.length; i++) {
String y[] = x[i].split("#");
if (y.length > 1) {
System.out.println("group: '" + y[0] + "' item: '" + y[1] + "'");
List<String> l = result.get(y[0]);
if(l==null){
l = new ArrayList<String>();
result.put(y[0], l);
}
l.add(y[1]);
}
}
System.out.println("###Returning values stored in map, as separate arrays");
for(Entry<String,List<String>> entry: result.entrySet()){
System.out.println("Group:" + entry.getKey());
//System.out.println("Items:");
List <String> l = entry.getValue();
// This is where the final array is
String[] finalArray = l.toArray(new String[1]);
for (int i = 0; i < finalArray.length; i++) {
System.out.println(finalArray[i]);
}
}

Categories