I am trying to open this file in java and i want to know what i am doing wrong. The in file lies in the same directory as my Java file, but i tried to open this with both netbeans and eclipse and it gave a file not found exception. Can someone help me open this file and read from it. I am really new to java files. Here is the code
import java.util.*;
import java.io.*;
public class Practice
{
public static void main(String[] args)throws IOException
{
FileReader fin = new FileReader("anagrams.in");
BufferedReader br = new BufferedReader(fin);
System.out.println(fin);
String string = "Madam Curie";
String test = "Radium came";
string = string.toLowerCase();
test = test.toLowerCase();
string = string.replaceAll("[^a-zA-Z0-9]+", "");
test = test.replaceAll("[^a-zA-Z0-9]+", "");
char[] array = string.toCharArray();
char[] array2 = test.toCharArray();
boolean flag = false;
HashMap hm = new HashMap();
for(int i = 0; i < array.length; i++)
{
hm.put(array[i], array[i]);
}
for(int i = 0; i < array2.length; i++)
{
if(hm.get(array2[i]) == null || test.length() != string.length())
{
flag = false;
i = array2.length;
}
else
{
flag = true;
}
}
System.out.println(flag);
}
}
A few tips:
Abide to proper code indentation
If you're using an IDE like Eclipse, it can automatically correct indentation for you
Develop debugging instinct
Try to get what the current working directory is, and list all the files in it
Refactor repetitive code
Writing paired statements like you did should immediately raise red flags
Effective Java 2nd Edition
Item 23: Don't use raw types in new code
Item 52: Refer to objects by their interfaces
Item 46: Prefer for-each loops to traditional for loops
Use sensible variable names
With regards to 2, try something like this:
public static void listDir() {
File current = new File(".");
System.out.println(current.getAbsolutePath());
for (String filename : current.list()) {
System.out.println(filename);
}
}
Then in your main, simply call listDir before everything else, and see if you're running the app from the right directory, and if there's a "anagrams.in" in the directory. Note that some platforms are case-sensitive.
With regards to 3 and 4, consider having a helper method like this:
static Set<Character> usedCharactersIn(String s) {
Set<Character> set = new HashSet<Character>();
for (char ch : s.toLowerCase().toCharArray()) {
set.add(ch);
}
return set;
}
Note how Set<E> is used instead of Map<K,V>. Looking at the rest of the code, you didn't seem to actually need a mapping, but rather a set of some sort (but more on that later).
You can then have something like this in main, which makes the logic very readable:
String s1 = ...;
String s2 = ...;
boolean isNotQuiteAnagram = (s1.length() == s2.length()) &&
usedCharactersIn(s1).containsAll(usedCharactersIn(s2));
Note how variables are now named rather sensibly, highlighting their roles. Note also that this logic does not quite determine that s1 is an anagram of s2 (consider e.g. "abb" and "aab"), but this is in fact what you were doing.
Since this looks like homework, I'll leave it up to you to try to figure out when two strings are anagrams.
See also
Java Coding Conventions
Java Language Guide/For-each loop
Java Tutorials/Collections Framework
Related questions
Why doesn't Java Map extends Collection?
Make sure that the file lies in the same directory as your .class file. It doesn't matter if it is in the same as your .java file or not.
Other than that, the only problem I can see is in your indentation, which doesn't matter.
The normal practice is to put resources in the runtime classpath or to add its path to the runtime classpath so that you can get it by the classloader. Using relative paths in Java IO is considered poor practice since it breaks portability. The relative path would be dependent on the current working directory over which you have totally no control from inside the Java code.
After having placed it in the classpath (assuming that it's in the same folder as the Java class itself), just do so:
BufferedReader reader = null;
try {
InputStream input = Practice.class.getResourceAsStream("anagrams.in");
reader = new BufferedReader(new InputStreamReader(input, "UTF-8")); // Or whatever encoding it is in.
// Process it.
// ...
} finally {
if (reader != null) try { reader.close(); } catch (IOException ignore) {}
}
Closing in finally is by the way mandatory to release the lock on the file after reading.
Put the anagrams.in file in the same location as the .class file. Then you will be able to read the file. And this should help you get some links on how to read from files in Java.
Related
I'm not very familiar with File & Scanner objects so please bear with me:
I'm attempting to have a scanner look through a file and see if a specific string exists, then return true/false - I thought there would be a method for this but either I'm reading the docs wrong or it doesn't exist.
What I'm able to come up with is the following but I'm sure there's a simpler way.
public boolean findString(File f, String s) throws FileNotFoundException {
Scanner scan = new Scanner(f);
if(scan.findWithinHorizon(s, 0) != null) {
return true;
} else {
return false;
}
}
Well, there are many ways to check whether a certain file contains a certain string, but I can't think of a single method which opens the file, scans for the given pattern and then returns a boolean indicating whether the pattern has been found within the file.
I think that use-case would be to small, as in many cases, you want to do more with the contents than only searching whether it contains a specific pattern. Often you want to process the file contents.
Regarding your code, it is already fairly short. However, I would change two things here. First, as scan.findWithinHorizon(s, 0) != null already is a boolean expression, you could immediately return it, instead of using if-else. Second, you should close the file you opened. You can use the try-with-resources construct for this.
Here is the updated code:
try (Scanner scan = new Scanner(f)) {
return scan.findWithinHorizon(s, 0) != null;
}
Note that this code finds a pattern. If you want to find a literal string, then use scan.findWithinHorizon(Pattern.compile(s, Pattern.LITERAL), 0).
More on finding a pattern in a file: this Stack Overflow post
More on try-with-resources: Oracle Java documentation, Baeldung
I would use a while-loop and simply use indexOf to compare the currentLine to your string.
public boolean findString(File f, String s) throws FileNotFoundException {
Scanner scan = new Scanner(f);
String currentLine;
while((currentLine = scanner.readLine()) != null) {
if(currentLine.indexOf(s)) {
return true;
}
}
return false;
}
An advantage of doing it this way is that you can also have an integer which you increase with every run of the loop to get the line in which the string is included (if you want/need to).
I installed word2Vec using this tutorial on by Ubuntu laptop. Is it completely necessary to install DL4J in order to implement word2Vec vectors in Java? I'm comfortable working in Eclipse and I'm not sure that I want all the other pre-requisites that DL4J wants me to install.
Ideally there would be a really easy way for me to just use the Java code I've already written (in Eclipse) and change a few lines -- so that word look-ups that I am doing would retrieve a word2Vec vector instead of the current retrieval process I'm using.
Also, I've looked into using GloVe, however, I do not have MatLab. Is it possible to use GloVe without MatLab? (I got an error while installing it because of this). If so, the same question as above goes... I have no idea how to implement it in Java.
What is preventing you from saving the word2vec (the C program) output in text format and then read the file with a Java piece of code and load the vectors in a hashmap keyed by the word string?
Some code snippets:
// Class to store a hashmap of wordvecs
public class WordVecs {
HashMap<String, WordVec> wordvecmap;
....
void loadFromTextFile() {
String wordvecFile = prop.getProperty("wordvecs.vecfile");
wordvecmap = new HashMap();
try (FileReader fr = new FileReader(wordvecFile);
BufferedReader br = new BufferedReader(fr)) {
String line;
while ((line = br.readLine()) != null) {
WordVec wv = new WordVec(line);
wordvecmap.put(wv.word, wv);
}
}
catch (Exception ex) { ex.printStackTrace(); }
}
....
}
// class for each wordvec
public class WordVec implements Comparable<WordVec> {
public WordVec(String line) {
String[] tokens = line.split("\\s+");
word = tokens[0];
vec = new float[tokens.length-1];
for (int i = 1; i < tokens.length; i++)
vec[i-1] = Float.parseFloat(tokens[i]);
norm = getNorm();
}
....
}
If you want to get the nearest neighbours for a given word, you can keep a list of N nearest pre-computed neighbours associated with each WordVec object.
Dl4j author here. Our word2vec implementation is targeted for people who need to have custom pipelines. I don't blame you for going the simple route here.
Our word2vec implementation is meant for when you want to do something with them not for messing around. The c word2vec format is pretty straight forward.
Here is parsing logic in java if you'd like:
https://github.com/deeplearning4j/deeplearning4j/blob/374609b2672e97737b9eb3ba12ee62fab6cfee55/deeplearning4j-scaleout/deeplearning4j-nlp/src/main/java/org/deeplearning4j/models/embeddings/loader/WordVectorSerializer.java#L113
Hope that helps a bit
This question already has answers here:
How do I create a file and write to it?
(35 answers)
Closed 8 years ago.
I'm having an issue of writing output to a text file. I'm not too sure on how to go about it. I've tried to write output by writing something along the lines of- Writer is an object of the printWriter class:
This is trimmed down substantially but it boils down to.
Writer.println(sortRI());
I can't write that statement as the method itself- and all methods in this class I'm trying to write to an output file for are void.
So my question is how do I write output to a text file from my methods which are void- they print out their results via a few print statements. Is there a way I can instantiate a writer and use the writer to print the methods. An example of one of the methods is shown below:
ZipCodeLocation[] data2 = new ZipCodeLocation[];
public class Processor
{
...
public void readData(){
...
}
public void findSpringfield()
{
System.out.println("------------------------------------------------------------------------");
System.out.println("SPRINGFIELD ZIP CODES");
for(int i=0; i < data2.length ; i++)
{
if(data2[i].getpostalCity().replaceAll("\"","").contains("SPRINGFIELD"))
{
System.out.println(data2[i].getzipCode().replaceAll("\"","")); //Prints out zipCodes that have Springfield in them
}
}
}
Instead of printing the message to System.out in the console, how could I have it write the output of the method to a text file?
You have asked a very good question, because it describes an instance of a design consideration common to all software.
The topic here is separation of business logic from interfaces. Even more generally, it's a discussion of well-defined responsibilities in an object-oriented program.
Ideally your business logic would return a data structure, which would allow the caller to do anything desired with the result, like write it to a file or display it in a web page.
public List<String> findSpringfield()
{
List<String> results = new ArrayList<String>();
for(int i=0; i < data2.length ; i++) {
if(data2[i].getpostalCity().contains("SPRINGFIELD")) {
results.add(data2[i].getzipCode().replaceAll("\"","")); //Collects zipCodes that have Springfield in them
}
}
return results;
}
If that's not an option, at the absolute minimum you would want to modify your methods to accept a PrintStream parameter.
public void findSpringfield(PrintStream out)
{
out.println("------------------------------------------------------------------------");
out.println("SPRINGFIELD ZIP CODES");
for(int i=0; i < data2.length ; i++) {
if(data2[i].getpostalCity().contains("SPRINGFIELD")) {
out.println(data2[i].getzipCode().replaceAll("\"","")); //Prints out zipCodes that have Springfield in them
}
}
}
That way you could call it like
findSpringfield(System.out);
Or you could pass it a different PrintStream instance than System.out, one that points to your own file.
Finally, if neither of the above options will work for you, I'm going to tell you how to do something which is very bad practice. You can redirect System.out to a file of your choosing. As I said, this is a terrible idea; use it only as a last resort in a very limited scope.
System.out = new PrintStream("somePath/someFile.txt");
Also, as a design improvement, consider generalizing your findSpringfield method to accept a String postalCity parameter so you can reuse it to find zip codes for other cities.
public List<String> zipsByCity(String postalCity)
{
// use postalCity to filter results, rather than hardcoded "SPRINGFIELD" string
}
Try sending in the Writer as an argument to the method and instead of printing to standard out inside the method, print to the writer:
public void findSpringfield(FileWriter writer)
{
writer.println("--------------------------------------------------- ---------------------");
writer.println("SPRINGFIELD ZIP CODES");
for(int i=0; i < data2.length ; i++)
{
if(data2[i].getpostalCity().replaceAll("\"","").contains("SPRINGFIELD"))
{
writer.println(data2[i].getzipCode().replaceAll("\"","")); //Prints out zipCodes that have Springfield in them
}
}
File file = new File("out.txt");
BufferedWriter output = new BufferedWriter(new FileWriter(file));
for(int i=0; i < data2.length ; i++){
if(data2[i].getpostalCity().replaceAll("\"","").contains("SPRINGFIELD")){
output.write(data2[i].getzipCode().replaceAll("\"",""));
}
}
output.close();
this should work but it will require a try-catch block or a throws declaration
The way it looks right now every single one of your methods has to implement writing to a file or get file writer as an argument. Both of those will work, but will be very ineficcient.
From what I understood from your question you will be having more of those void methods named findXYZ.
Why not write method void findTown(String townName)?
I might be wrong or get wrong impression of what you're trying to achieve but if I'm right then you're going in a wrong direction.
I have a text file and that file lists all the operations that can be performed on a Pump Class.
example of the content of text file
Start PayCredit Reject Start PayCredit Reject TurnOff
....
.... so on.
These are the methods of the Pump class(Start(), Reject() etc)
I need to write a code where I can Read these method from the file one by one and execute them.
public static void main(String[] args) throws IOException
{
Pump gp= new Pump();
File file=new File("C:\\Users\\Desktop\\checker\\check.txt");
BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(file)));
String line=null;
while((line=br.readLine())!=null)
{
String words[]=line.split(" ");
for(int i=0;i<words.length;i++)
{
String temp=words[i]+"()";
gp.temp; //compilation error
}
}
}
Could you tell me how can I achieve this functionality.
If you're not so familiar with reflection, maybe try using org.springframework.util.ReflectionUtils from the Spring Framework project?
The code would go something like this:
Pump gp = new Pump();
....
String temp = // from text file
....
Method m = ReflectionUtils.findMethod(Pump.class, temp);
Object result = ReflectionUtils.invokeMethod(m, gp);
You would need to use reflection to invoke the methods at runtime. Here is a simple example that assumes that all methods do not take any parameters.
Class<? extends Pump> pumpClass = gp.getClass();
String methodName = words[i];
Method toInvoke = pumpClass.getMethod(methodName);
if (null != toInvoke) {
toInvoke.invoke(gp);
}
First of all be aware that Java is not interpreted at runtime. So you can't do it this way.
If you already have the methods such as Start PayCredit Reject TurnOff and so on you can do it in the following way:
for(int i=0;i<words.length;i++)
{
String temp=words[i];
if (temp.equals("Start") gp.Start();
else if (temp.equals("PayCredit") gp.PayCredit();
...
}
use a switch case
for(int i=0;i<words.length;i++) {
String temp=words[i];
switch(temp) {
case "Start":
gp.start();
break;
case "PayCredit":
gp.PayCredit();
break;
}
}
You can use reflection to do this, e.g.
String line=null;
Method method = null;
while((line=br.readLine())!=null)
{
String words[]=line.split(" ");
for(int i=0;i<words.length;i++)
{
String temp=words[i];
method = getClass().getMethod(temp);
method.invoke(this);
}
}
That's assuming you want to call the method on this, of course, and that it's an instance method. Look at Class.getMethod and related methods, along with Method itself, for more details. You may want getDeclaredMethod instead, and you may need to make it accessible.
I would see if you can think of a way of avoiding this if possible though - reflection tends to get messy quickly. It's worth taking a step back and considering if this is the best design. If you give us more details of the bigger picture, we may be able to suggest alternatives.
how to list files and directories in current directory without using java.io.*?
This is actually possible without having to write any JNI or make any Runtime calls.
import java.net.URL;
import sun.net.www.content.text.PlainTextInputStream;
public class NoIO {
public static void main(String args[]) {
NoIO n = new NoIO();
n.doT();
}
public void doT() {
try {
//Create a URL from the user.dir (run directory)
//Prefix with the protocol file:/
//Users java.net
URL u = new URL("file:/"+System.getProperty("user.dir"));
//Get the contents of the URL (this basically prints out the directory
//list. Uses sun.net.www.content.text
PlainTextInputStream in = (PlainTextInputStream)u.getContent();
//Iterate over the InputStream and print it out.
int c;
while ((c = in.read()) != -1) {
System.out.print((char) c);
}
} catch(Exception e) {
e.printStackTrace();
}
}
}
It's amazing what a little thought and boredom will do (and an inability to jump to hasty conclusions (where there's a will, there's a way)).
You could probably also do it using the ClassLoader, by overriding it, at some point Java has to iterate over all the files in the classpath, by hooking at that point you can print out all the files that it tries to load without using any kind of java.io.*.
After some investigation I don't think this is possible very easily, certainly not for a homework assignment unless it's some kind of RE'ing assignment or Forensics assignment.
You can use Runtime.getRuntime().exec():
String[] cmdarray;
if (System.getProperty("os.name").startsWith("Windows")) {
cmdarray = new String[] { "cmd.exe", "/c", "dir /b" };
} else { // for UNIX-like systems
cmdarray = new String[] { "ls" };
}
Runtime.getRuntime().exec(cmdarray);
Thanks to #Geo for the Windows commands.
You could use JNA to make native calls to the underlying OS.
As an exercise in hard work it might be a worth while.
Another option is writing OS specific code in C and accessing it via JNI. But once again. Why do you want this?