I want to remove comma in last data.
example:
i have code:
StringBuilder temp = new StringBuilder();
for (int i=0; i<allLines.size(); i++){
StringBuilder temp2 = new StringBuilder();
String[] abc = line.split("\t");
temp2.append("{");
temp2.append("id: \""+abc[0]+"\",");
temp2.append("name: \""+abc[1]+"\",");
temp2.append("},");
temp.append(temp2.toString());
}
System.out.println("result : "+temp.toString());
ihave code and result:
{id: "1", name: "Jhames"},{id: "2", name: "Richard"},
but i want result:
{id: "1", name: "Jhames"},{id: "2", name: "Richard"}
Just use the new java 8 StringJoiner! (And other nifty Java methods)
Example:
StringJoiner joiner = new StringJoiner(",");
joiner.add("foo");
joiner.add("bar");
joiner.add("baz");
String joined = joiner.toString(); // "foo,bar,baz"
It also supports streams in the form of Collectors.joining(",")
Full example:
public static void main(String[] args) {
String input = "1\tJames\n2\tRichard";
String output = Arrays.stream(input.split("\n"))
.map( i -> String.format("{ id: \"%s\", name: \"%s\" }", i.split("\t")))
.collect(Collectors.joining(","));
//prints: { id: "1", name: "James" },{ id: "2", name: "Richard" }
System.out.println(output);
}
You can avoid appending it in the first place :
for (int i=0; i<allLines.size(); i++){
StringBuilder temp2 = new StringBuilder();
String[] abc = line.split("\t");
temp2.append("{");
temp2.append("id: \""+abc[0]+"\",");
temp2.append("name: \""+abc[1]+"\",");
temp2.append("}");
if (i<allLines.size()-1)
temp2.append(",");
temp.append(temp2.toString());
}
Alternatively add this after your for loop
temp.setLength(temp.length() - 1);
which requires no constant index checking in your code
You can use deleteCharAt() method.
StringBuilder s = new StringBuilder("{id: \"1\", name: \"Jhames\"},{id: \"2\", name: \"Richard\"},");
System.out.println(s.deleteCharAt(s.lastIndexOf(",")));
First of all you don't need two StringBuilders, so instead of
StringBuilder sb1 = ..
for(..){
StringBuilder sb2 = ...
//fill sb2
sb1.append(sb2);
}
you should use
StringBuilder sb1 = ..
for(..){
//add all you want to sb1
sb1.append(..)
sb1.append(..)
}
Next thing is that you don't ever want to do
sb.appent("foo" + x + "bar");
because it is same as
sb.append(new StringBuilder("foo").append(x).append("bar").toString())
which is very ineffective because:
you are creating separate StringBuilder each time you do so
this new StringBuilder needs to unnecessary call toString method which has to copy all characters to new String which will later be copied to builder, instead of calling append(StringBuilder) and copy its characters directly.
So instead of sb.appent("foo" + x + "bar"); always write
sb.appent("foo").append(x).append("bar");
Now lets go back to your main problem. Since your code doesn't have declaration of line variable I am assuming that by
String[] abc = line.split("\t");
you mean
String[] abc = allLines.get(i).split("\t");
So your code can look like
StringBuilder temp = new StringBuilder();
for (int i = 0; i < allLines.size(); i++) {
String[] abc = allLines.get(i).split("\t");
temp.append("{id: \"").append(abc[0]).append("\", ");
temp.append("name: \"").append(abc[1]).append("\"}");
if (i < allLines.size() - 1)
temp.append(", ");
}
System.out.println("result : " + temp.toString());
No Java 8 solution:
StringBuilder temp = new StringBuilder();
adder(temp, allLines.get(0));
for (int i=1; i<allLines.size(); i++){
temp.append(",");
adder(temp, allLines.get(i));
}
System.out.println("result : "+temp.toString());
private static void adder(StringBuilder temp,String line){
String[] abc = line.split("\t");
temp.append("{id: \"");
temp.append(abc[0]);
temp.append("\",");
temp.append("name: \"");
temp.append(abc[1]);
temp.append("\"}");
}
Related
I am trying to index each word in a text file Using java
Index means i am denoting indexing of words here..
This is my sample file https://pastebin.com/hxB8t56p
(the actual file I want to index is much larger)
This is the code I have tried so far
ArrayList<String> ar = new ArrayList<String>();
ArrayList<String> sen = new ArrayList<String>();
ArrayList<String> fin = new ArrayList<String>();
ArrayList<String> word = new ArrayList<String>();
String content = new String(Files.readAllBytes(Paths.get("D:\\folder\\poem.txt")), StandardCharsets.UTF_8);
String[] split = content.split("\\s"); // Split text file content
for(String b:split) {
ar.add(b); // added into the ar arraylist //ar contains every line of poem
}
FileInputStream fstream = null;
String answer = "";fstream=new FileInputStream("D:\\folder\\poemt.txt");
BufferedReader br = new BufferedReader(new InputStreamReader(fstream));
String strLine;
int count = 1;
int songnum = 0;
while((strLine=br.readLine())!=null) {
String text = strLine.replaceAll("[0-9]", ""); // Replace numbers from txt
String nums = strLine.split("(?=\\D)")[0]; // get digits from strLine
if (nums.matches(".*[0-9].*")) {
songnum = Integer.parseInt(nums); // Parse string to int
}
String regex = ".*\\d+.*";
boolean result = strLine.matches(regex);
if (result == true) { // check if strLine contain digit
count = 1;
}
answer = songnum + "." + count + "(" + text + ")";
count++;
sen.add(answer); // added songnum + line number and text to sen
}
for(int i = 0;i<sen.size();i++) { // loop to match and get word+poem number+line number
for (int j = 0; j < ar.size(); j++) {
if (sen.get(i).contains(ar.get(j))) {
if (!ar.get(j).isEmpty()) {
String x = ar.get(j) + " - " + sen.get(i);
x = x.replaceAll("\\(.*\\)", ""); // replace single line sentence
String[] sp = x.split("\\s+");
word.add(sp[0]); // each word in the poem is added to the word arraylist
fin.add(x); // word+poem number+line number
}
}
}
}
Set<String> listWithoutDuplicates = new LinkedHashSet<String>(fin); // Remove duplicates
fin.clear();fin.addAll(listWithoutDuplicates);
Locale lithuanian = new Locale("ta");
Collator lithuanianCollator = Collator.getInstance(lithuanian); // sort array
Collections.sort(fin,lithuanianCollator);
System.out.println(fin);
(change in blossom. - 0.2,1.2, & the - 0.1,1.2, & then - 0.1,1.2)
I will first copy the intended output for your pasted example, and then go over the code to find how to change it:
Poem.txt
0.And then the day came,
to remain blossom.
1.more painful
then the blossom.
Expected output
[blossom. - 0.2,1.2, came, - 0.1, day - 0.1, painful - 1.1, remain - 0.2, the - 0.1,1.2, then - 0.1,1.2, to - 0.2]
As #Pal Laden notes in comments, some words (the, and) are not being indexed. It is probable that stopwords are being ignored for indexing purposes.
Current output of code is
[blossom. - 0.2, blossom. - 1.2, came, - 0.1, day - 0.1, painful - 1.1, remain - 0.2, the - 0.1, the - 1.2, then - 0.1, then - 1.2, to - 0.2]
So, assuming you fix your stopwords, you are actually quite close. Your fin array contains word+poem number+line number, but it should contain word+*list* of poem number+line number. There are several ways to fix this. First, we will need to do stopword removal:
// build stopword-removal set "toIgnore"
String[] stopWords = new String[]{ "a", "the", "of", "more", /*others*/ };
Set<String> toIgnore = new HashSet<>();
for (String s: stopWords) toIgnore.add(s);
if ( ! toIgnore.contains(sp[0)) fin.add(x); // only process non-ignored words
// was: fin.add(x);
Now, lets fix the list problem. The easiest (but ugly) way is to fix "fin" at the very end:
List<String> fixed = new ArrayList<>();
String prevWord = "";
String prevLocs = "";
for (String s : fin) {
String[] parts = s.split(" - ");
if (parts[0].equals(prevWord)) {
prevLocs += "," + parts[1];
} else {
if (! prevWord.isEmpty()) fixed.add(prevWord + " - " + prevLocs);
prevWord = parts[0];
prevLocs = parts[1];
}
}
// last iteration
if (! prevWord.isEmpty()) fixed.add(prevWord + " - " + prevLocs);
System.out.println(fixed);
How to do it the right way (TM)
You code can be much improved. In particular, using flat ArrayLists for everything is not always the best idea. Maps are great for building indices:
// build stopwords
String[] stopWords = new String[]{ "and", "a", "the", "to", "of", "more", /*others*/ };
Set<String> toIgnore = new HashSet<>();
for (String s: stopWords) toIgnore.add(s);
// prepare always-sorted, quick-lookup set of terms
Collator lithuanianCollator = Collator.getInstance(new Locale("ta"));
Map<String, List<String>> terms = new TreeMap<>((o1, o2) -> lithuanianCollator.compare(o1, o2));
// read lines; if line starts with number, store separately
Pattern countPattern = Pattern.compile("([0-9]+)\\.(.*)");
String content = new String(Files.readAllBytes(Paths.get("/tmp/poem.txt")), StandardCharsets.UTF_8);
int poemCount = 0;
int lineCount = 1;
for (String line: content.split("[\n\r]+")) {
line = line.toLowerCase().trim(); // remove spaces on both sides
// update locations
Matcher m = countPattern.matcher(line);
if (m.matches()) {
poemCount = Integer.parseInt(m.group(1));
lineCount = 1;
line = m.group(2); // ignore number for word-finding purposes
} else {
lineCount ++;
}
// read words in line, with locations already taken care of
for (String word: line.split(" ")) {
if ( ! toIgnore.contains(word)) {
if ( ! terms.containsKey(word)) {
terms.put(word, new ArrayList<>());
}
terms.get(word).add(poemCount + "." + lineCount);
}
}
}
// output formatting to match that of your code
List<String> output = new ArrayList<>();
for (Map.Entry<String, List<String>> e: terms.entrySet()) {
output.add(e.getKey() + " - " + String.join(",", e.getValue()));
}
System.out.println(output);
Which gives me [blossom. - 0.2,1.2, came, - 0.1, day - 0.1, painful - 1.1, remain - 0.2, to - 0.2]. I have not fixed the list of stopwords to get a perfect match, but that should be easy to do.
I am trying to create 10 lines of 3 words using a string builder and random. Currently, I have two loops but not producing what I want.
public String generateRandSentences() {
}
}
return strBuilder.toString();
}
try to do it step by step you can replace these line
String rGenCharSet = sentences[rGen.nextInt(sentences.length)];
strBuilder.append(rGenCharSet + " ");
to
int randomnumber = rGen.nextInt(sentences.length);
String rGenCharSet = sentences[randomnumber];
strBuilder.append(rGenCharSet + " ");
and then try to print the string builder in output
Note that println() prints a string builder, as in:
System.out.println(sb);
because sb.toString() is called implicitly, as it is with any other object in a println() invocation.
It generates one line of 75 characters because a line separator is never inserted. Try adding strBuilder.append('\n') after each sentence is generated as in:
public String generateRandSentences() {
String[] sentences = {"mum", "can", "you", "get", "one", "bun", "for",
"guy", "one", "for", "gus", "his", "old", "man", "who"};
StringBuilder strBuilder = new StringBuilder();
Random rGen = new Random();
for (int row = 0; row < 5; row++) {
for (int words = 0; words < 15; words++) {
String rGenCharSet = sentences[rGen.nextInt(sentences.length)];
strBuilder.append(rGenCharSet + " ");
}
strBuilder.append('\n');
}
return strBuilder.toString();
}
TextView txtView1 = findViewById(R.id.txtview_vc_1);
txtView1.setText(generateRandSentences());
import java.util.*;
class Main {
public static void main(String[] args){
generateRandSentences();
}
public static void generateRandSentences() {
Random rGen = new Random();
String[] sentences = {"mum", "can", "you", "get", "one", "bun", "for","guy", "one", "for", "gus", "his", "old", "man", "who"};
int size = sentences.length;
for(int i = 0 ; i < 5 ; i++)
{
StringBuilder strBuilder = new StringBuilder();
for(int j = 0 ; j < 15 ; j++)
{
String str = sentences[rGen.nextInt(size)];
strBuilder.append(str + " ");
}
System.out.println(strBuilder.toString());
}
}
}
There is some line, for example "1 qqq 4 aaa 2" and list {aaa, qqq}. I must change all words (consists only from letters) on words from list. Answer on this example "1 aaa 4 qqq 2". Try
StringTokenizer tokenizer = new StringTokenizer(str, " ");
while (tokenizer.hasMoreTokens()){
tmp = tokenizer.nextToken();
if(tmp.matches("^[a-z]+$"))
newStr = newStr.replaceFirst(tmp, words.get(l++));
}
But it's not working. In result I have the same line.
All my code:
String space = " ", tmp, newStr;
Scanner stdin = new Scanner(System.in);
while (stdin.hasNextLine()) {
int k = 0, j = 0, l = 0;
String str = stdin.nextLine();
newStr = str;
List<String> words = new ArrayList<>(Arrays.asList(str.split(" ")));
words.removeIf(new Predicate<String>() {
#Override
public boolean test(String s) {
return !s.matches("^[a-z]+$");
}
});
Collections.sort(words);
StringTokenizer tokenizer = new StringTokenizer(str, " ");
while (tokenizer.hasMoreTokens()){
tmp = tokenizer.nextToken();
if(tmp.matches("^[a-z]+$"))
newStr = newStr.replaceFirst(tmp, words.get(l++));
}
System.out.printf(newStr);
}
I think the problem might be that replaceFirst() expects a regular expression as first parameter and you are giving it a String.
Maybe try
newStr = newStr.replaceFirst("^[a-z]+$", words.get(l++));
instead?
Update:
Would that be a possibility for you:
StringBuilder _b = new StringBuilder();
while (_tokenizer.hasMoreTokens()){
String _tmp = _tokenizer.nextToken();
if(_tmp.matches("^[a-z]+$")){
_b.append(words.get(l++));
}
else{
_b.append(_tmp);
}
_b.append(" ");
}
String newStr = _b.toString().trim();
Update 2:
Change the StringTokenizer like this:
StringTokenizer tokenizer = new StringTokenizer(str, " ", true);
That will also return the delimiters (all the spaces).
And then concatenate the String like this:
StringBuilder _b = new StringBuilder();
while (_tokenizer.hasMoreTokens()){
String _tmp = _tokenizer.nextToken();
if(_tmp.matches("^[a-z]+$")){
_b.append(words.get(l++));
}
else{
_b.append(_tmp);
}
}
String newStr = _b.toString().trim();
That should work.
Update 3:
As #DavidConrad mentioned StrinkTokenizer should not be used anymore. Here is another solution with String.split():
final String[] _elements = str.split("(?=[\\s]+)");
int l = 0;
for (int i = 0; i < _tokenizer.length; i++){
if(_tokenizer[i].matches("^[a-z]+$")){
_b.append(_arr[l++]);
}
else{
_b.append(_tokenizer[i]);
}
}
Just out of curiosity, another solution (the others really don't answer the question), which takes the input line and sorts the words alphabetically in the result, as you commented in your question.
public class Replacer {
public static void main(String[] args) {
Replacer r = new Replacer();
Scanner in = new Scanner(System.in);
while (in.hasNextLine()) {
System.out.println(r.replace(in.nextLine()));
}
}
public String replace(String input) {
Matcher m = Pattern.compile("([a-z]+)").matcher(input);
StringBuffer sb = new StringBuffer();
List<String> replacements = new ArrayList<>();
while (m.find()) {
replacements.add(m.group());
}
Collections.sort(replacements);
m.reset();
for (int i = 0; m.find(); i++) {
m.appendReplacement(sb, replacements.get(i));
}
m.appendTail(sb);
return sb.toString();
}
}
I want to convert a String Array to String so that later on while retrieving I can parse String to String[] with the help of (,) separator.
String [] ------------> String
//and later
String ---------------> String[]
Can someone guide on how to do this?
for (int i = 0; i <= count; i++) {
Log.d(TAG, "arrayData == " +arrayData[i]);
// Joining:
String joined = String.join(",", arrayData);
//This will give error "The method join(String, String[]) is undefined for the type String"
}
You can use String.join StringBuilder and String.split:
// Joining:
String joined = String.join(",", stringArr);
StringBuilder buffer = new StringBuilder();
for (String each : stringArr)
buffer.append(",").append(each);
String joined = buffer.deleteCharAt(0).toString();
// Splitting:
String[] splitted = joined.split(",");
In the input file, there are 2 columns: 1) stem, 2) affixes. In my coding, i recognise each of the columns as tokens i.e. tokens[1] and tokens[2]. However, for tokens[2] the contents are: ng ny nge
stem affixes
---- -------
nyak ng ny nge
my problem here, how can I declare the contents under tokens[2]? Below are my the snippet of the coding:
try {
FileInputStream fstream2 = new FileInputStream(file2);
DataInputStream in2 = new DataInputStream(fstream2);
BufferedReader br2 = new BufferedReader(new InputStreamReader(in2));
String str2 = "";
String affixes = " ";
while ((str2 = br2.readLine()) != null) {
System.out.println("Original:" + str2);
tokens = str2.split("\\s");
if (tokens.length < 4) {
continue;
}
String stem = tokens[1];
System.out.println("stem is: " + stem);
// here is my point
affixes = tokens[3].split(" ");
for (int x=0; x < tokens.length; x++)
System.out.println("affix is: " + affixes);
}
in2.close();
} catch (Exception e) {
System.err.println(e);
} //end of try2
You are using tokens as an array (tokens[1]) and assigning the value of a String.split(" ") to it. So it makes things clear that the type of tokens is a String[] array.
Next,
you are trying to set the value for affixes after splitting tokens[3], we know that tokens[3] is of type String so calling the split function on that string will yield another String[] array.
so the following is wrong because you are creating a String whereas you need String[]
String affixes = " ";
so the correct type should go like this:
String[] affixes = null;
then you can go ahead and assign it an array.
affixes = tokens[3].split(" ");
Are you looking for something like this?
public static void main(String[] args) {
String line = "nyak ng ny nge";
MyObject object = new MyObject(line);
System.out.println("Stem: " + object.stem);
System.out.println("Affixes: ");
for (String affix : object.affixes) {
System.out.println(" " + affix);
}
}
static class MyObject {
public final String stem;
public final String[] affixes;
public MyObject(String line) {
String[] stemSplit = line.split(" +", 2);
stem = stemSplit[0];
affixes = stemSplit[1].split(" +");
}
}
Output:
Stem: nyak
Affixes:
ng
ny
nge