Getting values from a string - java

I'm making a simple paint program and am stuck with getting a certain part of a string.
Here's the trouble - When I save the 9-panel image, it stores the RBG values of each panel to a .txt file. Example:
java.awt.Color[r=0,g=0,b=0]
java.awt.Color[r=255,g=255,b=255]
java.awt.Color[r=255,g=0,b=0]
java.awt.Color[r=0,g=0,b=255]
java.awt.Color[r=0,g=0,b=0]
java.awt.Color[r=255,g=255,b=0]
java.awt.Color[r=255,g=255,b=0]
java.awt.Color[r=255,g=0,b=0]
java.awt.Color[r=0,g=0,b=255]
From here, I call a scanner to read the lines of our file. I just need to find the best way to extract the values inside the [ ] to a String. I've tried using a tokenizer to no avail, still being stuck with excess Strings. I've tried manipulating characters but again failed. What would be the best way to go about extracting the data from our brackets? AND would it be easier to store the individual r=xxx, b=xxx, g=xxx values to a String[]? Thanks, and here is the source i have so far:
import java.awt.Color;
import java.io.*;
import java.lang.*;
import java.util.*;
//when finished, organize imports (narrow down what imports were used)
public class SaveLoad {
private boolean tryPassed, tryPassed2;
private Formatter x;
//final String[] rawData; will be where the rgb raws are stored
private Scanner xReader;
public void save(Color[] c, String s) {
//s is the filename
int counter = c.length;
//Tries to create a file and, if it does, adds the data to it.
try{
x = new Formatter(s+".txt");
tryPassed = true;
while(counter>0) {
x.format("%s. %s\n", (c.length-(counter-1)), c[counter-1]);
counter--;
}
x.close();
}catch (Exception e){
e.printStackTrace();
tryPassed = false;
}
}
//load will take paramaters of a filename(string); NOTE:::: make the file loaded specify an appendix (ex] .pixmap)
//MAYBE add a load interface with a jDropdownmenu for the filetype? add parameter String filetype.
public void load(String s, String filetype) {
//loads the file and, if successful, attempts to read it.
try{
xReader = new Scanner(new File(s+filetype));
tryPassed2 = true;
}catch(Exception e){
e.printStackTrace();
tryPassed2 = false;
System.out.println(s+filetype+" is not a valid file");
}
while(xReader.hasNext()&&tryPassed2==true) {
String inBrackets = xReader.next().substring(17);
System.out.println(inBrackets);
}
}
}
Also, ignore my messy notations.

The best way is to change the storage format. At least two options:
comma-separate values. Store r,g,b on each line. For example 215,222,213. Then you can have line.split(",") to obtain a String[] of the values
serialize the whole Color array using ObjectOutputStream

I would advise to change format. But if you insists on your one use regex:
String st = "java.awt.Color[r=0,g=0,b=0]";
Pattern p = Pattern.compile("java.awt.Color\\[r=(.*),g=(.*),b=(.*)\\]");
Matcher m = p.matcher(st);
if (m.matches()) {
System.out.println("r=" + m.group(1));
System.out.println("g=" + m.group(2));
System.out.println("b=" + m.group(3));
}

Related

How to fix wrong output of content.Equals?

I am trying to let Java read all files in a directory and compare the filenames to a list of strings, if a filename is the same as a string in the list it should output the filename + "hit". Now I get a hit on only one file.
the folder hit contains:
foto5.jpeg
yH1laMN0s7g.jpeg
RdrzTHAvcQg.jpeg
The list lijst.txt contains:
foto5.jpeg
yH1laMN0s7g.jpeg
RdrzTHAvcQg.jpeg
So I should get:
foto5 Hit!
RdrzTHAvcQg Hit!
yH1laMN0s7g Hit!
But what I get now is:
foto5 *
RdrzTHAvcQg Hit!
yH1laMN0s7g *
I have tried to play with the coding, which is now UTF-8. But I don't think that's the problem.
public static void main(String[] args) {
// TODO Auto-generated method stub
String hit = ""; // empty string
File files = new File("C:\\Users\\bram\\Pictures\\hit");
File[] sourceFiles = files.listFiles(); // the files in the map hit java reads
List<String> lines = new ArrayList<String>();
try {
lines = FileUtils.readLines(new File("C:\\lijst.txt"), "utf-8");
} catch (IOException e2) {
} // java reads strings in the list
for (File x: sourceFiles) { // java iterates through all the files in the folder hits.
String names = x.getName().replaceAll("\\.[^.]*$", "").toString();
// java gets the filenames and converts them to strings without the extension
for (String a : lines) // for all strings in the list:
{
//System.out.println(a);
if(names.contentEquals(a)) // if the name is equel to one of the strings in the list it generates a hit
{
hit = "Hit!";
}else {
hit = "*"; // no hit is *
}
}
System.out.println(x.getName().replaceAll("\\.[^.]*$", "").toString() +" "+ hit); // print the results
}
}
}
You are overcomplicating things. Why do you remove the file extensions although your txt file contains the full names of your images files? why a nested for loop? Dosen't something like below suffice?
for (File x : sourceFiles) {
if(lines.contains(x.getName())){
System.out.println(x.getName()+"\t Hit!");
}
else{
System.out.println(x.getName()+"\t *");
}
}
Allright, sorry guys.. It has been a long day. The list with the strings did not contain any extensions. Wrong information from my side, sorry.
I got it working now, with just a simple break in the for-loop. Thanks for the responses!
for (String a : lines) // for all strings in the list:
{
//System.out.println(a);
if(names.contentEquals(a))
{
hit = "Hit!";
break;
}else {
hit = "*"; // no hit is *
}
}

Implementing my Java Program in Talend : can't Drag & Drop

Here's the deal :
I was asked to developp a JAVA program that would do some reorganisations of .tsv files (moving cells to do some kind of transposition).
So, I tried to do it cleanly and got now 3 different packages:
.
Only tsvExceptions and tsvTranspositer are needed to make the main (TSVTransposer.java) work.
Yesterday I learned that I would have to implement it in Talend myself which I had never heard of.
So by searching, i stepped on this stackOverflow topic. So i followed the steps, creating a routine, copy/pasting my main inside it (changing the package to "routines") and added the external needed libraries to it (my two packages exported as jar files and openCSV). Now, when I open the routine, no error is showned but I can't drag & drop it to my created job !
Nothing happens. It just opens the component infos as shown with "Properties not available."
package routines;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import com.opencsv.CSVReader;
import com.opencsv.CSVWriter;
import tsvExceptions.ArgsExceptions;
import tsvExceptions.EmptyArgsException;
import tsvExceptions.OutOfBordersArgsException;
import tsvTranspositer.CommonLine;
import tsvTranspositer.HeadOfValuesHandler;
import tsvTranspositer.InputFile;
import tsvTranspositer.OutputFile;
public class tsvRoutine {
public static void main(String[] args) throws ArgsExceptions {
// Boolean set to true while everything is good
Boolean everythingOk = true;
String inputFile = null; // Name of the entry file to be transposed.
String outputFile = null; // Name of the output file.
int serieNb = 1 ; // Number of columns before the actual values in the input file. Can be columns describing the product as well as empty columns before the values.
int linesToCopy = 0; // Number of lines composing the header of the file (those lines will be copy/pasted in the output)
/*
* Handling the arguments first.
*/
try {
switch (args.length) {
case 0:
throw new EmptyArgsException();
case 1:
inputFile = args[0];
String[] parts = inputFile.split("\\.");
// If no outPutFile name is given, will add "Transposed" to the inputFile Name
outputFile = parts[0] + "Transposed." + parts[1];
break;
case 2:
inputFile = args[0];
outputFile = args[1];
break;
case 3:
inputFile = args[0];
outputFile = args[1];
serieNb = Integer.parseInt(args[2]);
break;
case 4:
inputFile = args[0];
outputFile = args[1];
serieNb = Integer.parseInt(args[2]);
linesToCopy = Integer.parseInt(args[3]);
break;
default:
inputFile = args[0];
outputFile = args[1];
serieNb = Integer.parseInt(args[2]);
linesToCopy = Integer.parseInt(args[3]);
throw new OutOfBordersArgsException();
}
}
catch (ArgsExceptions a) {
a.notOk(everythingOk);
}
catch (NumberFormatException n) {
System.out.println("Arguments 3 & 4 should be numbers."
+ " Number 3 is the Number of columns before the actual values in the input file. \n"
+ "(Can be columns describing the product as well as empty columns before the values. (1 by default)) \n"
+ "Number 4 is the number of lines to copy/pasta. (0 by default) \n"
+ "Please try again.");
everythingOk = false;
}
// Creating an InputFile and an OutputFile
InputFile ex1 = new InputFile(inputFile, linesToCopy);
OutputFile ex2 = new OutputFile(outputFile);
if (everythingOk) {
try ( FileReader fr = new FileReader(inputFile);
CSVReader reader = new CSVReader(fr, '\t', '\'', 0);
FileWriter fw = new FileWriter(outputFile);
CSVWriter writer = new CSVWriter(fw, '\t', CSVWriter.NO_QUOTE_CHARACTER))
{
ex1.setReader(reader);
ex2.setWriter(writer);
// Reading the header of the file
ex1.readHead();
// Writing the header of the file (copy/pasta)
ex2.write(ex1.getHeadFile());
// Handling the line containing the columns names
HeadOfValuesHandler handler = new HeadOfValuesHandler(ex1.readLine(), serieNb);
ex2.writeLine(handler.createOutputHOV());
// Each lien will be read and written (in multiple lines) one after the other.
String[] row;
CommonLine cl1;
// If the period is monthly
if (handler.isMonthly()) {
while (!ex1.isAllDone()) {
row = ex1.readLine();
if (!ex1.isAllDone()) {
cl1 = new CommonLine(row, handler.getYears(), handler.getMonths(), serieNb);
ex2.write(cl1.exportOutputLines());
}
}
}
// If the period is yearly
else {
while (!ex1.isAllDone()) {
row = ex1.readLine();
if (!ex1.isAllDone()) {
cl1 = new CommonLine(row, handler.getYears(), serieNb);
ex2.write(cl1.exportOutputLines());
}
}
}
}
catch (FileNotFoundException f) {
System.out.println(inputFile + " can't be found. Cancelling...");
}
catch (IOException e) {
System.out.println("Unknown exception raised.");
e.printStackTrace();
}
}
}
}
I know the exceptions aren't correctly handled yet, but they are in some kind of hurry for it to work in some way.
Another problem that will occur later is that I have no idea how to parse arguments to the program that are required.
Anyway, thanks for reading this post!
You cannot add routines per drag and drop to a job. You will need to access the routines functions through components.
For example, you would start with a tFileListInput to get all files you need. Then you could add a tFileInputDelimited where you describe all fields of your input. After this, with e.g. a tJavaRow component, you can write some code which would access your routine.
NOTE: Keep in mind that Talend works usually row-wise. This means that your routines should handle stuff in a row-wise manner. This could also mean that your code has to be refactored accordingly. A main function won't work, this has at least to become a class which can be instanciated or has static functions.
If you want to handle everything on your own, instead of a tJavaRow component you might use a tJava component which adds more flexibility.
Still, it won't be as easy as simply adding the routine and everything will work.
In fact, the whole code can become a job on its own. Talend generates the whole Java code for you:
The parameters can become Context variables.
The check if numbers are numbers could be done several ways, for example with a tPreJob and a tJava
Input file could be connected with a tFileInputDelimited with a dot separator
Then, every row will be processed with either a tJavaRow with your custom code or with a tMap if its not too complex.
Afterwards, you can write the file with a tFileOutputDelimited component
Everything will get connected via right click / main to iterate over the rows
All exception handling is done by Talend. If you want to react to exceptions, you can use a component like tLogRow.
Hope this helps a bit to set the direction.

How to read a file based on string position and store it in variable

I need to read a file, completely and split the strings inside the file and store it in a variable using Java
See below example, my text file contains
devarajan 1000210 08754540275 600019
ramesh 1000210 08754540275 600019
udhay 1000210 08754540275 600019
I tired using string position but it is not working out.
Please find attached sample file as well. Regards
My Code:
public class Program {
public static void main(String[] args) {
String line = "devarajan 1000210 08754540275 600019 ";
String[] words = line.split("\\W+");
for (String word : words) {
System.out.println(word);
}
}
}
Output:
devarajan 1000210 08754540276
My file will contain the list of string 10-10 position will be name 20-30 position will be empid 30-40 will phone number. so while i used the previous snippet i am getting blank spaces "devarajan" " 1000210".. i should avoid that blank spaces.
In turn my code is splitting up as soon as it encounters blank space, instead of position
#Twelve, # Kick : I am getting the output as follows for your snippet
but imagine if i have a space in my name ex: "twelve dollar" instead of "
twelvedollar", then the name will get split and stored in different array position. and that is the reason, i have asked whether it is possible to split the string based on the position
just one way to do it ..
try {
Scanner inFile = new Scanner(new File("myInputFile.txt"));
String[] data;
ArrayList<String[]> arr = new ArrayList<String[]>();
while (inFile.hasNext()) {
data = inFile.nextLine().split("\\s+"); // or split("\t") if using tabs
System.out.println(Arrays.toString(data));
arr.add(data);
}
}
catch (FileNotFoundException fe) {
fe.printStackTrace();
}

Writing big strings to a text file?

I have strings which look like this -
String text = "item1, item2, item3, item4 etc..."
I made java code to write these strings to a text file which will be converted to csv by simply changing the extension. The logic is - print a string, then move to new line and print another string.
Output in text file was perfect when test strings had only 10-20 items.
BUT, my real strings have about 3000 unique items each. There are about 20,000 such strings.
When i write all these strings to the text file, it gets messed up.
I see 3000 rows instead of 20,000 rows.
I think there is no need for code for this problem because its been done and tested.
I only need to be able to format my data properly.
For those who want to see the code -
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
public class Texty {
public static void main(String[] args) {
System.out.println("start");
String str = "";
String enter = System.getProperty( "line.separator" );
for(int i = 0; i< 5; i++){
str = str + i + ",";
}
str = str + 5;
System.out.println(str);
FileWriter fw = null;
File newTextFile = new File("C:\\filez\\output.txt");
try {
fw = new FileWriter(newTextFile);
} catch (IOException e) {
e.printStackTrace();
}
try {
for(int i = 0; i < 10; i++){
fw.write(str + enter);
}
fw.close();
} catch (IOException iox) {
//do stuff with exception
iox.printStackTrace();
}
System.out.println("stop");
}
}
You are right that there is no difference between 10 columns and 3000 columns, you just have longer lines
Also there is no difference between 10 rows and 20,000 rows, you juts have more lines.
While you can have much, much larger files in Java or on your files system, some old versions of excel could not load so many columns (it had a limit of 256 columns) or such large files (it had a limit of about 1 GB of raw data)
I would check the file is correct in another program e.g. one you wrote and you might find all the data is there.
If the data is not there, you have a bug, There is no limitation in Java or Windows or Linux which would explain the behaviour you are seeing.

saving random numbers in java

I'm doing an animation in Processing. I'm using random points and I need to execute the code twice for stereo vision.
I have lots of random variables in my code, so I should save it somewhere for the second run or re-generate the SAME string of "random" numbers any time I run the program. (as said here: http://www.coderanch.com/t/372076/java/java/save-random-numbers)
Is this approach possible? How? If I save the numbers in a txt file and then read it, will my program run slower? What's the best way to do this?
Thanks.
If you just need to be able to generate the same sequence for a limited time, seeding the random number generator with the same value to generate the same sequence is most likely the easiest and fastest way to go. Just make sure that any parallel threads always request their pseudo random numbers in the same sequence, or you'll be in trouble.
Note though that there afaik is nothing guaranteeing the same sequence if you update your Java VM or even run a patch, so if you want long time storage for your sequence, or want to be able to use it outside of your Java program, you need to save it to a file.
Here is a sample example:
public static void writeRandomDoublesToFile(String filePath, int numbersCount) throws IOException
{
FileOutputStream fos = new FileOutputStream(new File(filePath));
BufferedOutputStream bos = new BufferedOutputStream(fos);
DataOutputStream dos = new DataOutputStream(bos);
dos.writeInt(numbersCount);
for(int i = 0; i < numbersCount; i++) dos.writeDouble(Math.random());
}
public static double[] readRandomDoublesFromFile(String filePath) throws IOException
{
FileInputStream fis = new FileInputStream(new File(filePath));
BufferedInputStream bis = new BufferedInputStream(fis);
DataInputStream dis = new DataInputStream(bis);
int numbersCount = dis.readInt();
double[] result = new double[numbersCount];
for(int i = 0; i < numbersCount; i++) result[i] = dis.readDouble();
return result;
}
Well, there's a couple of ways that you can approach this problem. One of them would be to save the random variables as input into a file and pass that file name as a parameter to your program.
And you could do that in one of two ways, the first of which would be to use the args[] parameter:
import java.io.*;
import java.util.*;
public class bla {
public static void main(String[] args) {
// You'd need to put some verification code here to make
// sure that input was actually sent to the program.
Scanner in = new Scanner(new File(args[1]));
while(in.hasNextLine()) {
System.out.println(in.nextLine());
}
} }
Another way would be to use Scanner and read from the console input. It's all the same code as above, but instead of Scanner in = new Scanner(new File(args[1])); and all the verification code above that. You'd substitute Scanner in = new Scanner(System.in), but that's just to load the file.
The process of generating those points could be done in the following manner:
import java.util.*;
import java.io.*;
public class generator {
public static void main(String[] args) {
// You'd get some user input (or not) here
// that would ask for the file to save to,
// and that can be done by either using the
// scanner class like the input example above,
// or by using args, but in this case we'll
// just say:
String fileName = "somefile.txt";
FileWriter fstream = new FileWriter(fileName);
BufferedWriter out = new BufferedWriter(fstream);
out.write("Stuff");
out.close();
}
}
Both of those solutions are simple ways to read and write to and from a file in Java. However, if you deploy either of those solutions, you're still left with some kind of parsing of the data.
If it were me, I'd go for object serialization, and store a binary copy of the data structure I've already generated to disk rather than having to parse and reparse that information in an inefficient way. (Using text files, usually, takes up more disk space.)
And here's how you would do that (Here, I'm going to reuse code that has already been written, and comment on it along the way) Source
You declare some wrapper class that holds data (you don't always have to do this, by the way.)
public class Employee implements java.io.Serializable
{
public String name;
public String address;
public int transient SSN;
public int number;
public void mailCheck()
{
System.out.println("Mailing a check to " + name
+ " " + address);
}
}
And then, to serialize:
import java.io.*;
public class SerializeDemo
{
public static void main(String [] args)
{
Employee e = new Employee();
e.name = "Reyan Ali";
e.address = "Phokka Kuan, Ambehta Peer";
e.SSN = 11122333;
e.number = 101;
try
{
FileOutputStream fileOut =
new FileOutputStream("employee.ser");
ObjectOutputStream out =
new ObjectOutputStream(fileOut);
out.writeObject(e);
out.close();
fileOut.close();
}catch(IOException i)
{
i.printStackTrace();
}
}
}
And then, to deserialize:
import java.io.*;
public class DeserializeDemo
{
public static void main(String [] args)
{
Employee e = null;
try
{
FileInputStream fileIn =
new FileInputStream("employee.ser");
ObjectInputStream in = new ObjectInputStream(fileIn);
e = (Employee) in.readObject();
in.close();
fileIn.close();
}catch(IOException i)
{
i.printStackTrace();
return;
}catch(ClassNotFoundException c)
{
System.out.println(.Employee class not found.);
c.printStackTrace();
return;
}
System.out.println("Deserialized Employee...");
System.out.println("Name: " + e.name);
System.out.println("Address: " + e.address);
System.out.println("SSN: " + e.SSN);
System.out.println("Number: " + e.number);
}
}
Another alternative solution to your problem, that does not involve storing data, is to create a lazy generator for whatever function that provides you your random values, and provide the same seed each and every time. That way, you don't have to store any data at all.
However, that still is quite a bit slower (I think) than serializing the object to disk and loading it back up again. (Of course, that's a really subjective statement, but I'm not going to enumerate cases where that is not true). The advantage of doing that is so that it doesn't require any kind of storage at all.
Another way, that you may have not possibly thought of, is to create a wrapper around your generator function that memoizes the output -- meaning that data that has already been generated before will be retrieved from memory and will not have to be generated again if the same inputs are true. You can see some resources on that here: Memoization source
The idea behind memoizing your function calls is that you save time without persisting to disk. This is ideal if the same values are generated over and over and over again. Of course, for a set of random points, this isn't going to work very well if every point is unique, but keep that in the back of your mind.
The really interesting part comes when considering the ways that all the previous strategies I've described in this post can be combined together.
It'd be interesting to setup a Memoizer class, like described in the second page of 2 and then implement java.io.Serialization in that class. After that, you can add methods save(String fileName) and load(String fileName) in the memoizer class that make serialization and deserialization easier, so you can persist the cache used to memoize the function. Very useful.
Anyway, enough is enough. In short, just use the same seed value, and generate the same point pairs on the fly.

Categories