Promblem finding empty elements in a comma seperated data - java

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);
}

Related

Variable used in lambda should be final or effectively final for string appending

Java 8
i have a list of objects: myObjs,
each object has a method to get message.
Now i want to append these messages,
String myStr = new String();
myObjs.forEach( obj -> {
myStr = myStr.join(obj->getMessage());
})
Q1: how to solve: variable used in lambda should be final or effectively final java
Q2: how to separate each message with comma ?
I wrote a simple example program
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
public class Main {
public static void main(String[] args) {
List<Test> list = Arrays.asList(new Test(), new Test(), new Test());
String myStr = list.stream().map(Test::getMessage)
.collect(Collectors.joining(",", "optional prefix", "optional suffix"));
System.out.println(myStr); // output = optional prefixmessage,message,messageoptional suffix
}
}
class Test {
public String getMessage() {
return "message";
}
}
EDIT
If you have a List of Strings you could also do
List<String> stringList = Arrays.asList("a", "b", "c");
System.out.println(String.join(",", stringList));// a,b,c
You can't do this with a String and a lambda (because String is immutable, you can't mutate the reference in a lambda), but you can do this with a collector. Like,
String myStr = myObjs.stream().map(x -> x.getMessage()).collect(Collectors.joining(", "));
or a StringBuilder (but that's messier, and you'd need a check for comma and to manage that joining yourself). I prefer Collectors.joining

How to edit the contents of an ArrayList in-place while looping [duplicate]

This question already has answers here:
How to change value of ArrayList element in java
(7 answers)
Closed 6 years ago.
Assume I have an ArrayList of Strings that holds the words, "hello" and "world". I want to add the word "java" to the end of each.
I have tried to do it while looping, but did not succeed. Please suggest me a method for the same.
The other way, I found was to create a different ArrayList and copy contents, however I don't think is efficient in terms of space.
import java.util.ArrayList;
public class EditArrayListInLoop {
public static void main(String[] args) {
ArrayList<String> arrayList = new ArrayList<String>();
arrayList.add("hello");
arrayList.add("world");
/* This does not work */
/*for(int i = 0;i<arrayList.size();i++)
{
arrayList.get(i) += "java";
}*/
ArrayList<String> arrayList2 = new ArrayList<String>();
for(int i = 0;i<arrayList.size();i++)
{
String test = arrayList.get(i);
test += "java";
arrayList2.add(test);
}
System.out.println(arrayList2);
}
}
test += "java"; doesn't change the content of the String returned by arrayList.get(i). It creates a new String. Strings are immutable, so there isn't any way to change the String objects within the List. You can only replace them by new String objects.
Use arrayList.set(index,newValue) to replace the i'th element of the List:
for(int i = 0;i<arrayList.size();i++)
{
arrayList.set(i,arrayList.get(i)+"java");
}
I think you should manipulate the first list only. Using an another list is not an optimal solution.
Here's the code.
Output
[hellojava, worldjava]
Code
import java.util.ArrayList;
public class EditArrayListInLoop {
public static void main(String[] args) {
ArrayList<String> arrayList = new ArrayList<String>();
arrayList.add("hello");
arrayList.add("world");
for(int i = 0;i<arrayList.size();i++)
arrayList.set(i, arrayList.get(i).concat("java"));
System.out.println(arrayList);
}
}
Please note that Strings are immutable. Whenever you change the content of String, you're not actually appending anything behind the scenes. You are creating a completely new String.
If the contents of your Strings are expected to change, then the advisable way is to use the StringBuilder class instead:
Documentation
The principal operations on a StringBuilder are the append and insert
methods, which are overloaded so as to accept data of any type. Each
effectively converts a given datum to a string and then appends or
inserts the characters of that string to the string builder. The
append method always adds these characters at the end of the builder;
the insert method adds the characters at a specified point.
Here's the code:
import java.util.ArrayList;
public class EditArrayListInLoop {
public static void main(String[] args) {
ArrayList<StringBuilder> arrayList = new ArrayList<StringBuilder>();
arrayList.add(new StringBuilder("hello"));
arrayList.add(new StringBuilder("world"));
for(int i = 0;i<arrayList.size();i++)
arrayList.set(i, arrayList.get(i).append("java"));
System.out.println(arrayList);
}
}
P.S.: If such synchronization is required then it is recommended that StringBuffer be used.
try using the set method.
ArrayList<String> arrayList = new ArrayList<String>();
arrayList.add("hello");
arrayList.add("world");
for(int i = 0;i<arrayList.size();i++)
{
String str = arrayList.get(i);
arrayList.set(i, str + " java");
}
for(int i = 0;i<arrayList.size();i++)
{
String str = arrayList.get(i);
System.out.println(str);
}
You are looking for:
arrayList.set(i, arrayList.get(i) + "java");
More info on ArrayList: https://docs.oracle.com/javase/7/docs/api/java/util/ArrayList.html

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));
}

Built in method for removing duplicates in a string array

Is there a java built-in method for removing duplicates ? (array of strings)
Maybe using a Set ? in this case how can I use it ?
Thanks
Instead of an array of string, you can directly use a set (in this case all elements in set will always be unique of that type) but if you only want to use array of strings , you can use the following to save array to set then save it back.
import java.util.Arrays;
import java.util.HashSet;
public class HelloWorld{
public static void main(String []args)
{
String dupArray[] = {"hi","hello","hi"};
dupArray=removeDuplicates(dupArray);
for(String s: dupArray)
System.out.println(s);
}
public static String[] removeDuplicates(String []dupArray)
{
HashSet<String> mySet = new HashSet<String>(Arrays.asList(dupArray));
dupArray = new String[mySet.size()];
mySet.toArray(dupArray);
return dupArray;
}
}

Searching through Arraylist In Java for particular pattern

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.

Categories