I want to find ArrayList<String> item's index in String Array but every time indexOf() give -1 index .
I cant understand where is wrong? Please check my code and guide me.
public static void arrangeUiComponent() {
ArrayList<String> packageName = new ArrayList<String>();
packageName.add("com.example.dummy");
packageName.add("edu.app.reading");
ArrayList<Integer> index = getIndex(packageName);
}
// searching method
private static ArrayList<Integer> getIndex(ArrayList<String> searchName) {
ArrayList<Integer> indexList = new ArrayList<Integer>();
String[] collectionData = new String[] { "com.example.app",
"com.example.appdemo", "com.example.dummy", "edu.app.reading",
"edu.app.knowledge" };
/*
* for iterating each and every item of list
*/
for (int i = 0; i < searchName.size(); i++) {
Log.i("MISSION", "value will be: " + searchName.get(i).toString());
/*
* for searching listItem in package name array
*/
for (int j = 0; j < collectionData.length; j++) {
indexList.add(collectionData.toString().indexOf(searchName.get(i).toString()));
break;
}
}
return indexList;
}
Replace
for (int j = 0; j < collectionData.length; j++) {
indexList.add(collectionData.toString().indexOf(searchName.get(i).toString()));
break;
}
with
indexList.add(Arrays.asList(collectionData).indexOf(searchName.get(i)));
Here is the working demo of your code. Arrays.asList converts your string array to a list. Why don't you use a list instead of string collectionData array?
Use a debugger and look the value of collectionData.toString().
It returns something that is not your list of strings. That the object representation.
Quote from javadoc:
The toString method for class Object returns a string consisting of the name of the class of which the object is an instance, the at-sign character `#', and the unsigned hexadecimal representation of the hash code of the object.
EDIT:
whoops, collectionDatais an array, not a List, you should use
java.util.Arrays.asList(collectionData).indexOf(searchName.get(i))
It will search for the searchName.get(i)string inside the collectionDataList and not inside the collectionData representation which is a String (that's why indexOf is valid).
As searchName is a list of String, you don't need to add the toString() on searchName.get(i)
I'm assuming that in the indexLIst you want corresponding packageName's index values.
I don't think this will work in the way you want it.
The indexList being an Arraylist(data is not stored in the input order) might not have corresponding index values.
Ex:
packageName list:
"com.example.dummy", "edu.app.reading"
so the indexList should have values:
2 , 3
but it might contain:
3, 2 as well because data is not stored in the order in which it is entered.
You should probably use a linkedList if you want to preserve the order.
use a Hashmap<String, integer>.
You can do something like this using a hashmap:
public static void arrangeUiComponent() {
ArrayList<String> packageName = new ArrayList<String>();
packageName.add("com.example.dummy");
packageName.add("edu.app.reading");
HashMap<String, Integer> indexMap = getIndex(packageName);
for (String s : packageName) {
int index = indexMap.get(s);
}
}
private static HashMap<String, Integer> getIndex(ArrayList<String> searchName) {
HashMap<String, Integer> indexMap = new HashMap<String, Integer>();
String[] collectionData = new String[] { "com.example.app", "com.example.appdemo", "com.example.dummy",
"edu.app.reading", "edu.app.knowledge" };
for (String search : searchName) {
for (int i = 0; i < collectionData.length; i++) {
if (search.equals(collectionData[i])) {
indexMap.put(search, i);
break;
}
}
}
return indexMap;
}
You use collectionData.toString() which return [Ljava.lang.String;#15db9742. So collectionData.toString().indexof() always find nothing and return -1
To solve this you can use:
Declare arraylist as
ArrayList<String>cd = new ArrayList<String>(Arrays.asList(collectionData));
which convert String[] to ArrayList then ArrayList gives us facility of finding element with indexof().
Then in your inner for loop
for (int j = 0; j < collectionData.length; j++) {
indexList.add(cd.indexOf(searchName.get(i).toString()));
break;
}
toString() method of an array returns something similar to [Ljava.lang.String;#2a139a55. This is the reason you were getting index value as -1.
Other than the solution sam2090 provided, you can try 2 more options.
Replace
indexList.add(collectionData.toString().indexOf(searchName.get(i).toString()))
with
indexList.add(java.util.Arrays.binarySearch(collectionData, searchName.get(i)))
or
Replace collectionData.toString() with java.util.Arrays.toString(values)
Related
I have an arraylist containing some strings:
ArrayList<String> strList = new ArrayList<String>();
strList.addAll(Arrays.asList("interface", "list", "Primitive", "class", "primitive", "List", "Interface", "lIst", "Primitive"));
I have wrote a method to remove the case insensitive strings of the arraylist:
public static ArrayList<String> removeDuplicates(ArrayList<String> strList) {
for(int i = 0; i < strList.size(); i++) {
for(int j = i + 1; j < strList.size(); j++) {
if(strList.get(i).equalsIgnoreCase(strList.get(j))){
strList.remove(j);
j--;
}
}
}
return strList;
}
Ouput:
[interface, list, Primitive, class]
However, I am trying to remove just the first occurance of the strings. I am trying to make it so my output would equal:
[Interface, lIst, Primitive, class]
Which would be the last occurrences of the duplicates in the arraylist
What I'm trying to do specifically:
The version of the string that remains is the same as the last occurrence. In other words, the
version of the last occurrence stays at the location of the first occurrence
I think that remove from the ArrayList is not good idea. It is better using Map to create new list:
public static List<String> removeDuplicates(List<String> strList) {
Map<String, String> map = new LinkedHashMap<>();
strList.forEach(item -> map.put(item.toLowerCase(), item));
return new ArrayList<>(map.values());
}
Input: [interface, list, Primitive, class, primitive, List, Interface, lIst, Primitive]
Output: [Interface, lIst, Primitive, class]
P.S.
Same with one line Stream, but a bit not so clear:
public static List<String> removeDuplicates(List<String> strList) {
return new ArrayList<>(strList.stream().collect(Collectors.toMap(String::toLowerCase, str -> str, (prev, next) -> next, LinkedHashMap::new)).values());
}
Right now it keeps the first occurrence, so if you want to keep the last occurrence you can just go through the list in reverse:
for(int i = strList.size() - 1; i >= 0; i--) {
for(int j = i - 1; j >= 0; j--) {
...
I am having an array with name (String name[]={"a","b","a","c","a","b","c"};) and another array with quantity (int qty[]={10,20,10,40,10,40,70};) corresponding with name array. Now, i just want another array having addition of similar qty[] values corresponding to their name[] i.e. i need tempname[]={"a","b","c"} and tempqty[]={30,60,110}. here tempname contains unique values from name and tempqty contains addition of a,b,c.
temp=name;
qty1=qty;
for(i=0;i<name.length;i++){
temp1=qty[i];
for(int j=0;j<name.length;j++){
if (name[i]==temp[j+1]){
temp1=temp1+qty1[j+1];
}
}
}
I tried above method. Here, i am able to get addition of qty of "a" name but i am not getting my result. please suggest me on this or give me any another way to solve the problem. thank you in advance.
You can do this easily by ArrayList. I did this for you:
String name[]={"a","b","a","c","a","b","c"};
int qty[]={10,20,10,40,10,40,70};
ArrayList<String>tempname= new ArrayList<String>();
ArrayList<Integer>tempqty= new ArrayList<Integer>();
for(int i=0;i<name.length;i++){
int index=tempname.indexOf(name[i]);
if(index==-1){
tempname.add(name[i]);
tempqty.add(qty[i]);
}
else{
tempqty.set(index,tempqty.get(index)+qty[i]);
}
}
for(int i=0;i<tempname.size();i++){
System.out.printf(tempname.get(i)+" ");
}
System.out.println();
for(int i=0;i<tempqty.size();i++){
System.out.printf(tempqty.get(i)+" ");
}
Use a HashMap:
HashMap<String, Integer> quantity = new HashMap<>();
for(int i = 0; i < name.length; i++) {
if(!quantity.containsKey(name[i])) {
quantity.put(name[i], qty[i]);
} else {
quantity.put(name[i], quantity.get(name[i]) + qty[i]);
}
}
Untested, but you'll get the idea.
I suggest to use something like hashmaps for this
Example:
HashMap<String, int> hmap = new HashMap<String, int>();
hmap.put("a", 1);
hmap.put("b", 2);
To get a value use
hmap.get("a"); // will give 1
To loop through everything
Iterator it= hmap.keySet().iterator();
while(it.hasNext()) {
String key=(String)it.next();
int value=(int)hmap.get(key);
// do something
}
If you want to put values together because they belong together you could create a class.
class MyStoreThing {
String name;
int quantity;
}
int getSummarizedQuantityOfAllWithName(String name) {
int summarizedQuantity = 0;
for (int i = 0; i < myList.length; i++) {
summarizedQuantity += name.equals(myList.getName()) ? myList.getQuantity : 0;
}
return summarizedQuantity;
}
ArrayList<MyStoreThing> myList = new...;
// populate list: myList.add(new MyStoreThing("a", 10)) ...
// call getSummarizedQuantityOfAllWithName("a");
I have array lists of cities defined by state abbreviations.
static List<String> AL = Arrays.asList("ABBEVILLE","ADAMSVILLE",.....
static List<String> AK = Arrays.asList("ADAK","AKHIOK",......
The same thing happens to the array no matter which one is called. How do I pass a string of 'AL' and access the array list AL? I currently use a case statement... But its a lot of code for all 50 and I want to trim it down a bit..
case "AL":
for(int index = 0; index < AL.size(); index++){.....}
case "AK":
for(int index = 0; index < AK.size(); index++){.....}
Id rather something like this:
for(int index = 0; index < state_abbreviation.size(){
System.out.println(state_abbreviation[index]);
You could store every List<String> in a Map and use the state abbreviation as the map's key.
import java.util.*;
class Test {
public static void main(String[] args) {
Map<String, List<String>> states = new HashMap<String, List<String>>();
List<String> al = Arrays.asList("ABBEVILLE", "ADAMSVILLE", "...");
List<String> ak = Arrays.asList("ADAK", "AKHIOK", "...");
states.put("AL", al);
states.put("AK", ak);
System.out.println(states.get("AL").get(1)); // ADAMSVILLE
}
}
I am trying to remove duplicated words from an array, and I keep getting null values. I'm not allowed to use java sorting methods so I have to develop my own. Here's my code:
public class Duplicate{
public static void main(String[] args){
String[] test = {"a", "b", "abvc", "abccc", "a", "bbc", "ccc", "abc", "bbc"};
removeDuplicate(test);
}
public static String[] removeDuplicate(String[] words){
boolean [] isDuplicate = new boolean[words.length];
int i,j;
String[] tmp = new String[words.length];
for (i = 0; i < words.length ; i++){
if (isDuplicate[i])
continue;
for(j = 0; j < words.length ; j++){
if (words[i].equals(words[j])) {
isDuplicate[j] = true;
tmp[i] = words[i];
}
}
}
for(i=0;i<words.length;i++)
System.out.println(tmp[i]);
return tmp;
}
}
I tried doing
if(words == null)
words == "";
But it doesn't work. I also want to return the tmp array with a new size.
For example, test array length = 9, after removing the duplicates,I should get a new array with a length of 7.Thank you for your help.
EDIT:
result i get:
a
b
abvc
abccc
null
bbc
ccc
abc
null
You're getting nulls because the result array contains fewer words than the input array. However, you're constructing the arrays of the same length.
You don't have to sort to solve this problem. However, if you're not allowed to use the tools provided by java.utils, then this is either a poorly contrived test question or whomever told you not to use the Java utility classes is poorly informed.
You can solve without sorting by doing (assuming Java 1.5+):
public class Duplicate {
public static void main(String[] args) {
String[] test = {"a", "b", "abvc", "abccc", "a", "bbc", "ccc", "abc", "bbc"};
String[] deduped = removeDuplicate(test);
print(deduped);
}
public static String[] removeDuplicate(String[] words) {
Set<String> wordSet = new LinkedHashSet<String>();
for (String word : words) {
wordSet.add(word);
}
return wordSet.toArray(new String[wordSet.size()]);
}
public static void print(String[] words) {
for (String word : words) {
System.out.println(word);
}
}
}
The output will be:
a
b
abvc
abccc
bbc
ccc
abc
I would go for hashset to remove duplicates, it will remove duplicates since hash function for the same string will give same value, and duplicates will be eliminated. Then you can convert it to a string.
I would recommend doing this with a different approach. If you can use an ArrayList, why not just create one of those, and add the non-duplicate values to it, like this:
ArrayList<String> uniqueArrayList = new ArrayList<String>();
for(int i = 0; i < words.length; i++){
if(!uniqueArrayList.contains(words[i])){ // If the value isn't in the list already
uniqueArrayList.add(words[i]);
}
}
Now, you have an array list of all of your values without the duplicates. If you need to, you can work on converting that back to a regular array.
EDIT
I really think you should use the above option if you can, as there is no clean or decently efficient way to do this only using arrays. However, if you must, you can do something like this:
You can use the code you have to mark values as null if they are duplicates, and also create a counter to see how many unique values you have, like this:
int uniqueCounter = 0;
for(int i = 0; i < isDuplicate.length; i++){
if(!isDuplicate[i]){
uniqueCounter++;
}
}
Then, you can create a new array of the size of unique items, and loop through the words and add non-duplicate values.
String[] uniqueArray = new String[uniqueCounter];
int uniqueIndex = 0;
int wordsIndex = 0;
while(index < uniqueArray.length){
// Check if words index is not a duplicate
if(!isDuplicate[wordsIndex]){
// Add to array
uniqueArray[uniqueIndex] = words[wordsIndex];
uniqueIndex++; // Need to move to next spot in unique.
}
// Need to move to next spot in words
wordsIndex++;
}
Again, I HIGHLY recommend against something like this. It is very poor, and pains me to write, but for the sake of example on how it could be done using an array, you can try it.
I don't have the time to write functioning code, but I would reccomend to first sort the array using Arrays.sort(stringArray) and then loop throug the array coparing one string to the previous. Strings that match the previous one are duplicates.
Note: This method is probably not the fastest one and though only should be used on small arrays or in tasks where performance does not matter.
What about this approach?
public static String[] removeDuplicate(String[] words){
// remember which word is a duplicate
boolean[] isDuplicate = new boolean[words.length];
// and count them
int countDuplicate = 0;
for (int i = 0; i < words.length ; i++){
// only check "forward" because "backwards checked" duplicates have been marked yet
for(int j = i + 1; j < words.length ; j++){
if (words[i].equals(words[j])) {
isDuplicate[j] = true;
countDuplicate++;
}
}
}
// collect non-duplicate strings
String[] tmp = new String[words.length - countDuplicate];
int j = 0;
for (int i = 0; i < isDuplicate.length; i++) {
if (isDuplicate[i] == false) {
tmp[j] = words[i];
j++;
}
}
// and return them
return tmp;
}
Let's say I got this array:
String[][]array = new String[5][5];
array[2][2] = desperate;
Would it be possible to find whether
String s = "desperate"; - equals any array element without using a for loop, and without having to manually enter the row column combination of the array assigned the value "desperate"?
while loop instead of for loop
int i = 0;
int j = 0;
while (i < n)
{
while (j < m)
{
if (array[i][j].equals("..."))
{
///
}
j++;
}
i++;
}
Use enhanced-for loop: -
String [][] array = new String[2][2];
array[1][1] = "desperate";
array[0][1] = "despee";
array[1][0] = "despete";
array[0][0] = "dete";
for (String[] innerArr: array) {
for (String value: innerArr) {
if (value.equals("desperate")) {
System.out.println(value + " == desperate");
}
}
}
Output: - desperate == desperate
A better way that I would suggest is to use ArrayList<String> to store your items.. Then you can just call contains() method to check whether the list contains that element..
List<String> listString = new ArrayList<String>();
listString.add("desperate");
listString.add("despe");
if (listString.contains("desperate")) {
System.out.println("True");
}
Output: - True
Assuming that you can't (for any reasons) change your array to another collection type:
String[][]array = new String[5][5];
array[2][2] = "desperate";
public boolean contains(String str){
return new HashSet<String>((List<String>)Arrays.asList(array)).contains(str);
}
Better than transforming it to a List since HashSet's contains() method is O(1) and the one from List is O(n).
The only way to avoid using a loop (and it not clear why you would want to) is to use a Map which you pre-build with all the strings and indexes.