Java : add quotes to data in a CSV file - java

I am trying to add quotes to data in a CSV file. Below is the approach i have done it. I am sure there is a simpler way using regex or other methods. Would like to know that.
public List<String> addQuotes2List(List<String> list, String delimiter){
List<String> tempList = new ArrayList<>();
String temp="", value;
Integer i=-1, j=0;
for(String s1: list){
//println("S1 - "+s1+" - "+Arrays.asList(s1.split("\\"+delimiter)) );
i++;
tempList = Arrays.asList(s1.split("\\"+delimiter));
//println(tempList);
temp="";j=0;
for(String s2:tempList){
if(j>0)
temp+=delimiter;
//println("S2 - "+s2);
temp+="\""+s2+"\"";
j++;
}
list.set(i, temp);
}
return list;
}
Input
tempList.clear();
tempList.add("Sushanth.Bobby.Lloyds");
tempList.add("Watch.a.lot.of.movies");
tempList.add("main.hobby.is.programming");
tempList.add("programming.is.dangerous.addiction.of.all");
tempList = a.addQuotes2List(tempList,".");
println("tempList - "+tempList.size());
for(String s:tempList)
println(s);
output
tempList - 4
"Sushanth"."Bobby"."Lloyds"
"Watch"."a"."lot"."of"."movies"
"main"."hobby"."is"."programming"
"programming"."is"."dangerous"."addiction"."of"."all"
Thanks,
Sushanth

if you just handle the string .
you may just replce <.> to <"."> and append <"> on starts and ends .
public List<String> addQuotes2List2(List<String> list, String delimiter) {
List<String> tempList = new ArrayList<String>();
// null check list and delimiter
String rStr = "\""+delimiter+"\"";
String rmsg = "";
for (String s1 : list) {
rmsg = s1.replace(delimiter, rStr);
rmsg = "\""+rmsg+"\"";
tempList.add(rmsg);
}
return tempList;
}
regex may no necessary here. (replace and replaceAll made by regex)

If you're using Java 8, you can use streams to make it more readable.
public List<String> addQuotes2List(List<String> list, String delimiter){
return list.stream()
.map(line -> line.split("\\"+delimiter))
.map(this::addQuotes)
.map(entries -> String.join(delimiter, entries))
.collect(Collectors.toList());
}
private List<String> addQuotes(String[] entries) {
return Arrays.stream(entries)
.map(entry -> String.format("%s", entry))
.collect(Collectors.toList());
}

Related

Java Stream: How to change only first element of stream?

There is an ArrayList:
public void mainMethod() {
List<String> list = new ArrayList<>();
list.add("'+7913152','2020-05-25 00:00:25'");
list.add("'8912345','2020-05-25 00:01:49'");
list.add("'916952','2020-05-25 00:01:55'");
}
and method which transforms a string:
public String doTransform(String phone) {
String correctNumber;
..... make some changes...
return correctNumber;
}
list.stream().forEach(line -> {
Arrays.stream(line.split(","))... and what else?
How to take only first element of sub-stream (Arrays.stream) and pass it to transforming method?
"doTransform()" method is implemented, so don't care about it.
I just need to separate '+7913152', '8912345' and '916952', pass it to doTransform() and get an new List:
"'8913152','2020-05-25 00:00:25'"
"'8912345','2020-05-25 00:01:49'"
"'8916952','2020-05-25 00:01:55'"
Do it as follows:
List<String> result = list.stream()
.map(s -> {
String[] parts = s.split(",");
String st = doTransform(String.valueOf(Integer.parseInt(parts[0].replace("'", ""))));
return ("'" + st + "'") + "," + parts[1];
}).collect(Collectors.toList());
Demo:
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
public class Main {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("'+7913152','2020-05-25 00:00:25'");
list.add("'8912345','2020-05-25 00:01:49'");
list.add("'916952','2020-05-25 00:01:55'");
List<String> result = list.stream()
.map(s -> {
String[] parts = s.split(",");
String st = doTransform(String.valueOf(Integer.parseInt(parts[0].replace("'", ""))));
return ("'" + st + "'") + "," + parts[1];
}).collect(Collectors.toList());
// Display
result.forEach(System.out::println);
}
static String doTransform(String phone) {
return "x" + phone;
}
}
Output:
'x7913152','2020-05-25 00:00:25'
'x8912345','2020-05-25 00:01:49'
'x916952','2020-05-25 00:01:55'
I am assuming that length of the phone no in string as e.g "'+7913152','2020-05-25 00:00:25'" will be 7 if it's more than that you are going the remove the rest numbers from the head and replace with 8 to make it valid number else if number length is less than 7 then you will simply append the 8, Note: you can handle if the length of the number is like 3 or 4 etc.
public class PlayWithStream {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("'+7913152','2020-05-25 00:00:25'");
list.add("'8912345','2020-05-25 00:01:49'");
list.add("'916952','2020-05-25 00:01:55'");
List<String> collect = list.stream()
.map(PlayWithStream::doTransform)
.collect(Collectors.toList());
System.out.println(collect);
}
public static String doTransform(String phone1) {
String []a=phone1.split(",");
String phone=a[0];
boolean flag2 = phone.substring(0, 1).matches("[8]");
String finaloutput="";
if(!flag2) {
int len=phone.length();
if(len>7) {
String sub=phone.substring(0,phone.length()-6);
String newStr=phone.replace(sub, "");
finaloutput="8".concat(newStr);
}else {
finaloutput="8".concat(phone);
}
}
return finaloutput+","+a[1];
}
}
We can split elements using , in only two parts (initial which need to be change and remaining String) using limit on split String split.
List<String> list = list.stream()
.map(input -> input.split(",", 2))
.map(data -> String.join(",", doTransaform(data[0]), data[1]))
.collect(Collectors.toList());
It can be helpful when your string has multiple commas (,) separated parts and will surely improve efficiency too.
The below code works,
List<String> collect = list.stream()
.map(a -> a.replace(String.valueOf(a.charAt(1)), "2"))
.collect(Collectors.toList());

Remove Duplicates from List of String

I have the following List of String:
{
"Name1,Name2",
"Name2,Name1",
"Name3,Name4",
"Name4,Name3"
}
Without using any Java/C/Python/C++/C# library, I want to remove the duplicates in a way that, it prints:
Name1,Name2
Name3,Name4
One way to remove duplicates would be this:
private static boolean checkIfEquals(String str, String str1) {
HashSet<String> set1 = new HashSet<>(Arrays.asList(str.split(",")));
HashSet<String> set2 = new HashSet<>(Arrays.asList(str1.split(",")));
return set1.equals(set2);
}
Using your same approach, assuming your list of strings is in a variable List<String> strings:
List<String> unique =
strings.stream()
.map(str -> new LinkedHashSet<>(Arrays.asList(str.split(","))))
.distinct()
.map(set -> set.stream().collect(Collectors.joining(",")))
.collect(Collectors.toList());
using c++
int main(){
ios_base::sync_with_stdio(false);
string list[4]={
"Name1,Name2",
"Name2,Name1",
"Name3,Name4",
"Name4,Name3"
};
map<string,bool>exist;
vector<string>flist;
for(int i=0;i<4;i++){
string s=list[i];
sort(s.begin(),s.end());
if(exist[s])continue;
exist[s]=true;
flist.push_back(list[i]);
}
for(auto item :flist)cout<<item<<"\n";
}

Split csv file using lambda expression

I'm trying to refactor this method to use a lambda expression:
public List<String> getHttpsLinksFromCsvList() {
List<String> data = getDataFromCsv();
List<String> httpLinks = new ArrayList<>();
data.forEach(System.out::println);
for (String value : data) {
String[] arrayString = value.split(COMMA_DELIMITER);
for (String item : arrayString) {
if (item.endsWith(".git")) {
httpLinks.add(item);
}
}
}
//httpLinks.forEach(System.out::println);
return httpLinks;
}
Ideally I want to get remove the two nested for loops and optimise it a bit. Is it possible?
Try this:
List<String> httpLinks = getDataFromCsv().stream()
.map(value -> value.split(COMMA_DELIMITER))
.flatMap(Arrays::stream)
.filter(item -> item.endsWith(".git"))
.collect(Collectors.toList());

Convert nested loops into streams Java 8

I am trying to convert the below nested loop in to streams Java 8.
Each element in newself2 is a list of string - ["1 2","3 4"] needs to change to ["1","2","3","4"].
for (List<String> list : newself2) {
// cartesian = [["1 2","3 4"],["4 5","6 8"]...] list = ["1 2","3 4"]...
List<String> clearner = new ArrayList<String>();
for (String string : list) { //string = "1 3 4 5"
for (String stringElement : string.split(" ")) {
clearner.add(stringElement);
}
}
newself.add(clearner);
//[["1","2","3","4"],["4","5","6","8"]...]
}
What I have tried till now -
newself2.streams().forEach(list -> list.foreach(y -> y.split(" ")))
Now I am now sure how to add the split array in the inner for loop to a new list for x?
Any help is greatly appreciated.
Here's how I'd do it:
List<List<String>> result = newself2.stream()
.map(list -> list.stream()
.flatMap(string -> Arrays.stream(string.split(" ")))
.collect(Collectors.toList()))
.collect(Collectors.toList());
This is other solution.
Function<List<String>,List<String>> function = list->Arrays.asList(list.stream()
.reduce("",(s, s2) -> s.concat(s2.replace(" ",",")+",")).split(","));
and use this function
List<List<String>> finalResult = lists
.stream()
.map(function::apply)
.collect(Collectors.toList());
with for loop is similar to this:
List<List<String>> finalResult = new ArrayList<>();
for (List<String> list : lists) {
String acc = "";
for (String s : list) {
acc = acc.concat(s.replace(" ", ",") + ",");
}
finalResult.add(Arrays.asList(acc.split(",")));
}

How to split different type of string in a List

I have a list which contains list of values like below
[a-xyz,b-yzx,c-aaa,d-rrr,a-qqq,b-hhh]
and i need the above list like below
[xyz,yzx,aaa,rrr,qqq,hhh]
There a several things that should be done here. First, you need to get rid of the enclosing [] so the string could be split. Then, you need to actually split it (by commas). Then, for each string, you need to remove the prefix before the -. Java 8's stream give you a pretty neat way of doing this:
List<String> result =
Arrays.stream(str.substring(1, str.length() - 1).split(","))
.map(s -> s.replaceFirst("\\w-", ""))
.collect(Collectors.toList());
EDIT:
In JDK 7 and below the solution would be similar, but you'd have to resort to using loops instead of streams:
String[] arr = str.substring(1, str.length() - 1).split(",");
List<Stirng> result = new ArrayList<>(arr.length);
for (String s : arr) {
result.add(s.replaceFirst("\\w-", ""));
}
Try this
List<String> list = Arrays.asList("a-xyz","b-yzx","c-aaa","d-rrr","a-qqq","b-hhh");
List<String> result = list.stream()
.map(s -> s.replaceFirst("^.*-", ""))
.collect(Collectors.toList());
System.out.println(result);
result:
[xyz, yzx, aaa, rrr, qqq, hhh]
Or Java7
List<String> list = Arrays.asList("a-xyz","b-yzx","c-aaa","d-rrr","a-qqq","b-hhh");
List<String> result = new ArrayList<>();
for (String s : list)
result.add(s.replaceFirst("^.*-", ""));
System.out.println(result);
call me old-fashioned
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class Split {
public static void main(String[] args) {
String[] ss = {"a-xyz","b-yzx","c-aaa","d-rrr","a-qqq","b-hhh"};
List<String> ll = new ArrayList<>();
ll.addAll(Arrays.asList(ss));
List<String> result = new ArrayList<>();
for(String s:ll) {
result.add(s.split("-")[1]);
}
System.out.println(result);
}
}
gives
[xyz, yzx, aaa, rrr, qqq, hhh]
You can use same list to store final value using set method of list.
import java.util.ArrayList;
public class SplitList {
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<>();
list.add("a-xyz");
list.add("b-yzx");
list.add("c-aaa");
list.add("d-rrr");
list.add("a-qqq");
list.add("b-hhh");
for(String st : list){
int index = list.indexOf(st); //get index of string
list.set(index,st.replaceFirst("\\w-", "")); //set only with required value
}
for(String st : list){
System.out.println(st);
}
}
}

Categories