Searching through Arraylist In Java for particular pattern - java

Consider I have an Arraylist which holds products name like
Dell Inspiron Laptop
Apple iPad
Samsung S4
I want to have a search like if one searches for S4, it returns Samsung S4. I tried to find the answer in many websites but didn't get one. I used .matches and .contains but was of no use.

Iterate the product names list, assume the variable for product name is name, which is a String type.
You can use if (name.contains(value)) { or if(name.indexOf(value)!=-1){ to check whether the name contains the value to be searched.
Have a try with the following code:
import java.util.ArrayList;
import java.util.List;
public class Test {
public static void main(String[] args) {
List<String> prodNames = new ArrayList<String>();
prodNames.add("Dell Inspiron Laptop");
prodNames.add("Apple iPad");
prodNames.add("Samsung S4");
// Search S4 and it will print Samsung S4 in Console
System.out.println(search("S4", prodNames));
}
public static String search(String value, List<String> prodNames) {
for (String name : prodNames) {
if (name.contains(value)) {
return name;
}
}
return null;
}
}

You can write an utility function like below, that scans through contents of list for particular pattern. Hope this works for your.
public static void findMatch(List<String> listNames, String searchTerm){
for(String inName:listNames){
if(inName!=null)
if(inName.contains(searchTerm))
System.out.println(" Match Found for "+inName);
}
}

You could do something like:
public List<String> matches (List<String> dataList, String matchStr){
List<String> result = new ArrayList<String>();
if (matchStr != null) {
matchStr = matchStr.toLowerCase();
for(String d : dataList){
if (d.toLowerCase().contains(matchStr)) {
result.add(d);
}
}
}
return result;
}

First of all clean up the definition of the Array. I'm guessing that it actually looks like this:
{ "Dell Inspiron", "Apple iPad", "Samsung S4" }
Then go run this in your IDE :
import java.util.ArrayList;
import java.util.List;
class TestSearching {
public static void main(String args[]) {
List<String> products = new ArrayList<String>();
products.add("Dell Inspiron");
products.add("Apple iPad");
products.add("Samsung S4");
System.out.println("Matches to S4 : " + findMatches(products,"S4"));
}
public static List<String> findMatches(List<String> products, String searchTerm) {
List<String> result = new ArrayList<String>();
for (String product : products) {
if ( product.contains(searchTerm) ) result.add(product);
}
return result;
}
}

If you always want to do a lookup on the string after the first space, then maybe you don't want to use an ArrayList
Maybe you should use a Map<String, String> of product, full name e.g. "S4", "Samsung S4"
Then lookups will be much faster.

Related

If matched then add elements of ArrayList_A to ArrayList , if not then add elements of ArrayList_B to ArrayList

I have the following code:
package sportsCardsTracker;
import java.io.*;
import java.text.*;
import java.util.*;
import java.util.stream.Collectors;
public class Test_Mark6 {
public static ArrayList<String> listingNameList;
public static ArrayList<String> finalNamesList;
public static void main(String[] args) throws IOException, ParseException {
listingNameList = new ArrayList();
listingNameList.add("LeBron James 2017-18 Hoops Card");
listingNameList.add("Stephen Curry Auto Patch, HOT INVESTMENTS!");
listingNameList.add("Michael Jordan 1998 Jersey Worn Card");
ArrayList<String> playersNamesList = new ArrayList();
playersNamesList.add("LeBron James");
playersNamesList.add("Stephen Curry");
playersNamesList.add("Michael Jordan");
finalNamesList = new ArrayList();
String directory = System.getProperty("user.dir");
File file = new File(directory + "/src/sportsCardsTracker/CardPrices.csv");
FileWriter fw = new FileWriter(file, false); //true to not over ride
for (int i = 0; i < listingNameList.size(); i++) {
for (String listingNames : listingNameList) {
List<String> result = NBARostersScraper_Mark3.getNBARoster().stream().map(String::toLowerCase).collect(Collectors.toList());
boolean valueContained = result.stream().anyMatch(s -> listingNames.toLowerCase().matches(".*" + s + ".*"));
if(valueContained == true) {
finalNamesList.add(//The players' name);
}
}
fw.write(String.format("%s, %s\n", finalNamesList.get(i)));
}
}
}
Basically, in the listingsNameList, I have the listing's names and in the playersNamesList, I have all the players' names. What I would like is that, if the code matches the names between the two arrayList and find a player's name, it should returns the players' only.
For example, instead of "LeBron James 2017-18 Hoops Card" it should return "Lebron James" only. If it does not find anything, then just return the listing's name. So far, I have created a new ArrayList namely finalNamesList, my idea would be using an if statement (if match found then add players' name to finalNamesList, if not add the listing' name to finalNamesList). However the code above is not working and it is just adding all of the names in the listingNameList to the finalNamesList. I suspect that the way I grab the index is wrong - but I don't know how to fix it.
The method you are using to match a pattern that seems wrong. Instead of "match()" you can use string contains method as below.
List<String> temp = new ArrayList<>();
for (String listingNames : listingNameList) {
temp = playersNamesList.parallelStream().filter(s -> listingNames.toLowerCase().contains(s.toLowerCase())).map(s -> s).collect(Collectors.toList());
if(temp.size() > 0){
System.out.println(temp.get(0));
//fw.write(String.format("%s, %s\n", temp.get(0));
}
}
One more thing, You don't need to use 2 for loop here, with one loop you can achieve your output.
Though You can still optimize this code, I have taken the temp list above that you can avoid.

Type mismatch: convert from String to List<String>

I have in mind the algorithm of my school-class program, but also difficulty in some basics I guess...
here is my code with the problem:
import java.io.*;
import java.util.*;
public class Main {
public static void main(String[] args) throws FileNotFoundException {
String allWords = System.getProperty("user.home") + "/allwords.txt";
Anagrams an = new Anagrams(allWords);
for(List<String> wlist : an.getSortedByAnQty()) {
//[..............];
}
}
}
public class Anagrams {
List<String> myList = new ArrayList<String>();
public List<String> getSortedByAnQty() {
myList.add("aaa");
return myList;
}
}
I get "Type mismatch: cannot convert from element type String to List"
How should initialise getSortedByAnQty() right?
an.getSortedByAnQty() returns a List<String>. When you iterate over that List, you get the individual Strings, so the enhanced for loop should have a String variable :
for(String str : an.getSortedByAnQty()) {
//[..............];
}
If the main method should remain as is, you should change getSortedByAnQty to return a List<List<String>>.
char[] cArray = "MYString".toCharArray();
convert the string to an array as above and then iterate over the character array to form a list of String as below
List<String> list = new ArrayList<String>(cArray.length);
for(char c : cArray){
list.add(String.valueOf(c));
}

Java Mapping range of IDs to Strings in List

I have the following code that will get me a list of all the country names :D
private List<String> countriesList = new ArrayList<String>();
public List<String> getCountriesList() {
String[] locales = Locale.getISOCountries();
for (String countryCode : locales) {
Locale obj = new Locale("", countryCode);
countriesList.add(obj.getDisplayCountry(Locale.ENGLISH));
}
Collections.sort(countriesList);
countriesList.add(0, "International");
System.out.println(countriesList);
return countriesList;
}
What I need to do is now map all these countries to an ID number.
The ID number will start at: 32000006 and end at 32000260
I am not sure what I need to do to get the numbers mapped.. I know that basically I will pass an int through a method and then that method will match the ID that is passed through to the method and then I need it to return the country name.
I am not sure about how to go about this but one problem I have noticed is that ID 32000008 belongs to the country: Ă…land Islands but as it has a weird A it is at the end of my List. I still need it to have the ID 32000008 though.
If anyone has any idea about what I need to do to my method to finish this off I will be grateful.
Thanks :)
UPDATE
I tried using a HashMap and got this code:
public class test{
public static void main (String[] args) throws java.lang.Exception
{
getCountriesList();
}
private static HashMap<Integer,String> countriesList = new HashMap<Integer,String>();
public static void getCountriesList() {
String[] locales = Locale.getISOCountries();
for (String countryCode : locales) {
int i = 32000007;
Locale obj = new Locale("", countryCode);
countriesList.put(i,obj.getDisplayCountry(Locale.ENGLISH));
i++;
}
countriesList.put(32000006,"International");
System.out.println(countriesList);
}
}
Which outputs:
{32000006=International, 32000007=Zimbabwe}
Any ideas why it isn't working?
i is a local variable of the loop. So at each iteration, it's reinitialized to 32000007. The variable must be declared out of the loop:
int i = 32000007;
for (String countryCode : locales) {
Locale obj = new Locale("", countryCode);
countriesList.put(i,obj.getDisplayCountry(Locale.ENGLISH));
i++;
}
That said, instead of having a list of strings, and a map of IDs to strings, why don't you create a Country class with two fields: ID and label. Then use a loop to create a List<Country>? That would be much cleaner.
String[] locales = Locale.getISOCountries();
List<Country> countries = new ArrayList<>();
int i = 32000007;
for (String countryCode : locales) {
Locale obj = new Locale("", countryCode);
countries.add(new Country(i, obj.getDisplayCountry(Locale.ENGLISH)));
i++;
}

Promblem finding empty elements in a comma seperated data

import java.util.ArrayList;
import java.util.StringTokenizer;
public class test {
public static void main(String args[]) {
ArrayList<String> data = new ArrayList<String>();
String s = "a,b,c,d,e,f,g";
StringTokenizer st = new StringTokenizer(s,",");
while(st.hasMoreTokens()){
data.add(st.nextToken());
}
System.out.println(data);
}
}
Problem in finding empty elements in a CSV data
the above code works well when the data is complete. If some data is missing it fails to detect the empty data.
ex:
Complete DATA : a,b,c,d,e,f,g
if a,d,e,g are removed
New DATA : ,b,c,,,f,
4 data missing!!
I need a way to put this data into ArrayList with null or "" values for empty data
You can use Guava Splitter to do that:
import com.google.common.base.Splitter;
public class Example
{
private static final Splitter SPLITTER = Splitter.on(",").trimResults();
public List<String> split(String singleLine) {
return SPLITTER.split(singleLine);
}
}
I'm sure there are more elegant solutions, but a simple one would be to use split() function:
public static void main(String args[]) {
ArrayList<String> data = new ArrayList<String>();
String s = ",b,c,,,f,";
//create an array of strings, using "," as a delimiter
//if there is no letter between commas, an empty string will be
//placed in strings[] instead
String[] strings = s.split(",", -1);
for (String ss : strings) {
data.add(ss);
}
System.out.println(data);
}

For Each Loop to return search string

I'm having trouble with my JAVA command line menu. Here's what I've got.. what I want to do is in the comments.
private void listStudents(){
out.println("\n\tStudent Listing");
//Call datastore method that returns all student names as an array of strings
String[] list = data.getStudents();
//Display all names (use foreach statement)
for (String name : list) {
}
}
here's the data store method I'm also stuck with...
String[] getStudents() {
return (String[]) students.toArray();
}
// Method to return students who match search term
String[] findStudents(String searchTerms) {
// Use foreach loop to visit each item in students ArrayList,
// and if the name matches the search term, add it to a new ArraList.
// Then return the new ArrayList as a string array (see getStudents)
}
Not sure if this is exactly what you need, but based on what I understood from your comments, try using the following:
private void listStudents()
{
System.out.println("\n\tStudent Listing");
String[] list = data.getStudents();
// List each student.
for (String name : list)
System.out.println(name);
}
private String[] findStudents(String searchTerms)
{
List<String> studentsFound = new ArrayList<String>();
for (String student : students)
{
// Determine if matching student found.
if (student.equals(searchTerms))
studentsFound.add(student);
}
return studentsFound.toArray(new String[0]);
}
You've not defined what the searchterms might. Is it a regular expression? Is it a wildcard?
public String[] findStudents(String searchTerms) {
List<String> findList = new ArrayList<String>(25);
for (String student : students) {
// Now you'll need to define how the match works,
// Are you using a regexp or some kind of other matching
// algorithm..
boolean match = ...;
if (match) {
findList.add(student);
}
}
return findList.toArray(new String[findList.size()]);
}

Categories