Using java .util.Map & java .util.LinkedHashMap? - java

I am new to Java (along with programming in general). I was working on a personal project where a user types one character to which it is converted to another character. More specifically, a user would type a romanization of a Japanese character to which the Japanese hiragana equivalent is outputted. I am using two separate classes at the moment:
RomaHiraCore.java
import java.util.*;
public class RomaHiraCore
{
public static void main(String[] args)
{
Table.initialize(); // Table.java needed!
Map<String, String> table = Table.getTable();
Scanner roma = new Scanner(System.in);
System.out.println("Romaji: ");
String romaji = roma.nextLine().toLowerCase();
if (table.containsKey(roma))
{
System.out.println(table.get(roma));
}
else
{
System.out.println("Please enter a valid character (e. g. a, ka)");
}
roma.close();
}
}
Tables.java
import java.util.*;
public class Table
{
private static Map<String, String> table = new LinkedHashMap<>();
public static Map<String, String> getTable()
{
return table;
}
public static void initialize()
{
// a - o
table.put("a", "あ");
table.put("i", "い");
table.put("u", "う");
table.put("e", "え");
table.put("o", "お");
// ka - ko
table.put("ka", "か");
table.put("ki", "き");
table.put("ku", "く");
table.put("ke", "け");
table.put("ko", "こ");
}
}
If anyone can point me in the right direction, I would greatly appreciate it. I've attempted to go over the documentation, but I can't seem to grasp it (maybe I'm overthinking it). When I run the program, it allows me to enter a character; however, it will only continue to the "else" statement rather than scan Table.java to see if the input matches any of the values listed. Either I'm overlooking something or need to use an entirely different method altogether.

In your map, you have String keys, and the String which you provide is in the romaji variable. So your if should look like this: if (table.containsKey(romaji)). What is more, in this situation I think that using LinkedHashMap doesn't give you anything, simple HashMap would be as good as LinkedHashMap(even better), because you don't need to maintain insertion order of your characters.

In your main method, you are currently storing the string value inputted by the user however you never access that variable anywhere else.
You wrote table.containsKey(roma) however roma is the Scanner object and not the string they entered so you should be checking if that string is a valid key by using table.containsKey(romaji).
Next, in your else clause, you ask them to reenter an input but never provide them the chance to because you just terminate the scanner.
What you should be doing is something more like this.
String romaji = roma.nextLine().toLowerCase();
while (true) {
if (table.containsKey(romaji)) {
System.out.println(table.get(romaji));
break;
}
else {
System.out.println("Enter a valid char:";
romaji = roma.nextLine().toLowerCase();
}
}
roma.close();

Related

Putting words from an input file into canonical form

I'm trying to write a code where it takes words from a text file, and puts each word in canonical order, and when run prints the original word next to its canonical form like this:
coding cdgino
games aegms
All I have so far is this:
import java.util.*;
import java.io.*;
public class CanonicalWords
{
public static void main(String[] args) throws Exception
{
if (args.length<1)
{
System.out.println("You must provide an input file.");
system.exit(0);
}
String infileName = args[0];
BufferedRead infile = new BufferedReader(new FileReader(infileName));
while(infile.ready())
{
//arraylist.add(infile.readLine())
}
//sort arraylist
for (int i=0;i<arrayList.size;i++)
{
}
}
static String canonical(String word)
{
char[] canonicalWord = word.toCharArray();
Arrays.sort(canonicalWord);
String cWord = new String(canonicalWord);
return cWord;
}
}
Please let me know if you need clarification on anything I have writen. I do not know how to take these words to put them into canonical form.
Right now there is no real output, it doesn't even compile. I'm just very confused. If someone could help me to understand what is the basic formula (if there is one) to put words into canonical form and do what I stated above that'd be wonderful, but I understand that what I'm asking may come off as a bit confusing. Thank you.
First, from the looks of this code:
BufferedRead infile = new BufferedReader(new FileReader(infileName));
should look like this:
BufferedReader infile = new BufferedReader(new FileReader(infileName));
Be careful that you fully spell out correctly; variable names and they're data types!
Another thing to take note of is, the method:
static String canonical(String word)
isn't being called. Try accessing it in the main method.

Multiple if statements having incorrect output [duplicate]

This question already has answers here:
Multiple if statements with single else statement
(2 answers)
Closed 6 years ago.
I want to fill the acts array with values of some enum. While iterating I want to input commands from console, but my if statements don't find any match and I always get the output "Incorrect".
My code:
Action[] acts = new Action[n];
for(int i = 0; i < n; i++) {
System.out.println("Enter act: ");
Scanner in1 = new Scanner(System.in);
String s = in1.next();
acts[i] = new Action();
if (s.equals("rotate_forw"))
acts[i].type = ActionType.RotF;
if (s.equals("rotate_back"))
acts[i].type = ActionType.RotB;
if (s.equals("shift_forw"))
acts[i].type = ActionType.ShiftF;
if (s.equals("shift_back"))
acts[i].type = ActionType.ShiftB;
else
System.out.println("Incorrect");
}
Your else clause applies only to the last if statement, so you get the "Incorrect" output whenever s.equals("shift_back") is false.
Your statements should be replaced with a single if-else-if...-else statement, so that "Incorrect" is only printed if all the conditions are false :
Action[] acts = new Action[n];
for(int i = 0; i < n; i++) {
if (s.equals("rotate_forw"))
acts[i].type = ActionType.RotF;
else if (s.equals("rotate_back"))
acts[i].type = ActionType.RotB;
else if (s.equals("shift_forw"))
acts[i].type = ActionType.ShiftF;
else if (s.equals("shift_back"))
acts[i].type = ActionType.ShiftB;
else
System.out.println("Incorrect");
}
You should also consider what you want to assign to acts[i].type when the input is incorrect. Perhaps you should throw an exception in this case.
While #Eran's answer is correct, I'd like to suggest a different approach that encapsulates the enum with the translation from the external coding. Consider this:
public class EnumDemo
{
public static enum ActionType
{
Incorrect(""),
RotF("rotate_forw"),
RotB("rotate_back"),
ShiftF("shift_forw"),
ShiftB("shift_back");
private String code;
private ActionType(String code)
{
this.code = code;
}
public static ActionType fromString(String code)
{
return Arrays.stream(ActionType.values())
.filter(v->v.code.equals(code))
.findFirst()
.orElse(ActionType.Incorrect);
}
}
public static void main(String[] args)
{
String[] testData = {
"rotate_forw",
"rotate_back",
"shift_forw",
"shift_back",
"junk",
null };
Arrays.stream(testData)
.forEach(t->System.out.printf("\"%s\" -> ActionType.%s\n", t, ActionType.fromString(t)));
}
}
This uses the fact that enum constants can have associated data. I've added an instance variable code to hold the external encoding of each enum value. Then I added a static fromString(String code) method to the enum that looks up the provided code in the list of values. For 4 possibilities a simple linear search, equivalent to your if-then-else cascade, works fine. If there were dozens or more I'd set up a Map<String,ActionType> to handle the conversion.
The search using streams bears some explanation.
First create a Stream of enum values
Filter it to contain only enum values whose code matches the desired code (there should be only one)
Pick off the first entry, which comes back in a Optional. If nothing was found (i.e. the code is invalid) the Optional will be empty.
Use the orElse method to return the value if it exists or ActionType.Incorrect if not.
At first glance this might look inefficient since one expects that the filter() predicate has to scan the entire stream even if the desired element occurs early. This is a really nifty feature of Streams -- all intermediate streams are "lazy", so the filter won't iterate over the entire list if it finds the desired entry early. See this question for details.
Output:
"rotate_forw" -> ActionType.RotF
"rotate_back" -> ActionType.RotB
"shift_forw" -> ActionType.ShiftF
"shift_back" -> ActionType.ShiftB
"junk" -> ActionType.Incorrect
"null" -> ActionType.Incorrect
The last testcase shows the code is null-safe.
The biggest advantage is that the mapping is in the same place as the enum itself, so you won't have to hunt for the code when you add or remove an enum value. Also you can't forget to define the mapping since it's required by the enum's constructor.

Advise to create a translator in Java

I want to make a translator ex: English to Spanish.
I want to translate a large text with a map for the translation.
HashMap <String, Object> hashmap = new HashMap <String, Object>();
hashmap.put("hello", "holla");
.
.
.
Witch object should I use to handle my inital text of 1000 words? A String or StringBuilder is fine ?
How can I do a large replace? Without iterate each word with each element of the map ?
I don't want take each word of the string, and see there is a match in my map
Maybe a multimap with the first letter of the word?
If you have any answer or advise thank you
Here is an example implementation:
import java.io.*;
import java.util.*;
public class Translator {
public enum Language {
EN, ES
}
private static final String TRANSLATION_TEMPLATE = "translation_%s_%s.properties";
private final Properties translations = new Properties();
public Translator(Language from, Language to) {
String translationFile = String.format(TRANSLATION_TEMPLATE, from, to);
try (InputStream is = getClass().getResourceAsStream(translationFile)) {
translations.load(is);
} catch (final IOException e) {
throw new RuntimeException("Could not read: " + translationFile, e);
}
}
private String[] translate(String text) {
String[] source = normalizeText(text);
List<String> translation = new ArrayList<>();
for (String sourceWord : source) {
translation.add(translateWord(sourceWord));
}
return translation.toArray(new String[source.length]);
}
private String translateWord(String sourceWord) {
Object value = translations.get(sourceWord);
String translatedWord;
if (value != null) {
translatedWord = String.valueOf(value);
}
else {
// if no translation is found, add the source word with a question mark
translatedWord = sourceWord + "?";
}
return translatedWord;
}
private String[] normalizeText(String text) {
String alphaText = text.replaceAll("[^A-Za-z]", " ");
return alphaText.split("\\s+");
}
public static void main(final String[] args) {
final Translator translator = new Translator(Language.EN, Language.ES);
System.out.println(Arrays.toString(translator.translate("hello world!")));
}
}
And put a file called 'translation_EN_ES.properties' on your classpath (e.g. src/main/resources) with:
hello=holla
world=mundo
If you know all the words before hand you could easily create a Regex Trie.
Then at runtime, compile the regex once. Then you are good to go.
To create the regex, download and install RegexFormat 5 here.
From the main menu, select Tools -> Strings to Regex - Ternary Tree
paste the list in the input box, then press the Generate button.
It spits out a full regex Trie that is as fast as any hash lookup there is.
Copy the compressed output from that dialog into Rxform tab (mdi) window.
Right click window to get the Context menu, select Misc Utilities -> Line Wrap
set it for about a 60 character width, press ok.
Next press the C++ button from the windows toolbar to bring up the MegaString
dialog. Click make C-style strings Lines Catenated-1 press OK.
Copy and paste the result into your Java source.
Use the regex in a Replace-All with callback.
In the callback use the match as a key into your hash table to return the
translation to replace.
Its simple, one pass and oh so fast.
For a more extreme example of the tool see this regex of a 130,000 word dictionary.
Sample of the letter X
"(?:x(?:anth(?:a(?:m|n|te(?:s)?)|e(?:in|ne)|i(?:an|"
"c|n(?:e)?|um)|o(?:ma(?:s|ta)?|psia|us|xyl))|e(?:be"
"c(?:s)?|n(?:arthral|i(?:a(?:l)?|um)|o(?:biotic|cry"
"st(?:s)?|g(?:amy|enous|raft(?:s)?)|lith(?:s)?|mani"
"a|n|ph(?:ile(?:s)?|ob(?:e(?:s)?|ia|y)|ya)|time))|r"
"(?:a(?:fin(?:s)?|n(?:sis|tic)|rch|sia)|ic|o(?:derm"
"(?:a|i(?:a|c))|graphy|m(?:a(?:s|ta)?|orph(?:s)?)|p"
"h(?:agy|ily|yt(?:e(?:s)?|ic))|s(?:is|tom(?:a|ia))|"
"t(?:es|ic))))|i(?:pho(?:id(?:al)?|pag(?:ic|us)|sur"
"an))?|oan(?:a|on)|u|y(?:l(?:e(?:m|n(?:e(?:s)?|ol(?"
":s)?))|i(?:c|tol)|o(?:carp(?:s)?|g(?:en(?:ous)?|ra"
"ph(?:s|y)?)|id(?:in)?|l(?:ogy|s)?|m(?:a(?:s)?|eter"
"(?:s)?)|nic|ph(?:ag(?:an|e(?:s)?)|on(?:e(?:s)?|ic)"
")|rimba(?:s)?|se|tomous)|yl(?:s)?)|st(?:er(?:s)?|i"
"|o(?:i|s)|s|us)?)))"

Switch or if statements in writing an interpreter in java

Current assignment needs me to write a program to read a file with instructions in a very tiny and basic programming language (behaves a little like FORTRAN) and execute those instructions. Basically it's a simple interpreter for the language I guess. It's completely linear, with statements all being defined in sequence and it only has String and integer variables. There are 8 keywords and 4 arithmetic operators I would need to find and define if they exist within the source file, and each line must start off with one of the reserved words.
A program in this language might look something like this:
#COMMENTS
LET.... (declares variables with values)
INTEGER myINT
STRING myString
CALCULATE...
PRINT
PRINTLN
END
Can I use a switch block instead of if-loops to find and then execute all these? My concern is that switches don't work with Strings in Java 6, which is what I'm supposed to be using, but I don't see how to easily assign various int values so the switch block would work. Thanks in advance for any suggestions and advice!
If your language is so simple that every statement begins in its own line and is identified by one word only, then (as Gray pointed out in another comment) you can split the words in each line, then compare the first word against a map. However, I would suggest, instead of mapping the words to ints and then doing one big switch, to map them into objects instead, like this (suggested by Dave Newton):
interface Directive {
public void execute(String line);
}
class LetDirective implements Directive {
public void execute(String line) { ...handle LET directive here... }
}
...define other directives in the same way...
Then define the map:
private Map<String, Directive> directives = new HashMap<String, Directive>();
directives.put("LET", new LetDirective());
...
Then in your parsing method:
int firstSpace = line.indexOf(' ');
String command = line;
if (firstSpace > 0)
command = line.substring(0, firstSpace);
Directive directive = directives.get(command.toUpperCase());
if (directive != null)
directive.execute(line);
else
...show some error...
Each directive would have to parse the rest of the line on its own and handle it correctly inside its execute() method.
The benefit of this over a switch is that you can handle a larger amount of commands without ending up with one gigantic method, but instead with one smaller method per each command.
If you are talking about converting strings to integers then you could do it with an Java enumerated type:
private enum ReservedWord {
LET,
...
}
// skip blank lines and comments
String[] tokens = codeLine.split(" ");
ReservedWord keyword;
try {
keyword = ReservedWord.valueOf(tokens[0]);
} catch (IllegalArgumentException e) {
// spit out nice syntax error message
}
You could also put the processing of the line inside of the enum as a method if you'd like. You could also do it with a Map:
private final Map<String, Integer> reservedWords = new HashMap<String, Integer>();
private final int RESERVED_WORD_LET 1
...
{
reservedWords.put("LET", RESERVED_WORD_LET);
...
}
// skip blank lines and comments
String[] tokens = codeLine.split(" ");
Integer value = reservedWords.get(tokens[0]);
if (value == null) // handle error... ;
switch (value) {
case 1:
// LET
...
}

Retrieve user account

I used the following coding to display user accounts in my domain.But in that coding it display only first 100 records.But in my domain nearly 500 users account.I don't know what problem in this coding
import java.net.URL;
import java.util.List;
import com.google.gdata.client.appsforyourdomain.UserService;
import com.google.gdata.data.appsforyourdomain.provisioning.UserEntry;
import com.google.gdata.data.appsforyourdomain.provisioning.UserFeed;
public class Readuser {
public int i3;
public String rn[]=new String[100];
public void read(){
try
{
// Create a new Apps Provisioning service
UserService myService = new UserService("My Application");
myService.setUserCredentials(admin,password);
// Get a list of all entries
URL metafeedUrl = new URL("https://www.google.com/a/feeds/"+domain+"/user/2.0/");
System.out.println("Getting user entries...\n");
UserFeed resultFeed = myService.getFeed(metafeedUrl, UserFeed.class);
List<UserEntry> entries = resultFeed.getEntries();
for(i3=0; i3<entries.size(); i3++) {
UserEntry entry = entries.get(i3);
rn[i3]= entry.getTitle().getPlainText();
System.out.println(rn[i3]);
}
System.out.println("\nTotal Entries: "+entries.size());
}
catch(Exception e) { System.out.print(e);}
}
public static void main(String args[])
{
Readuser ru=new Readuser();
ru.read();
}
}
You only allocate 100 entries.
public String rn[]=new String[100];
Hint from your code : public String rn[]=new String[100];
Do you really need to have i3 and rn as class members ? Do you really need rn ? A List seems more comfortable as an Object than a String[].
There is no need for the string array (String[]).
Arrays are fixed size; and in this case you have allocated 100 "slots" for Strings, and when You try to assign a string to position 100 ( you know, the 101:th string) it fails.
You catch an exception in the end. Print the stack trace to find out whats going on
catch(Exception e) {
e.printStackTrace();
}
Learn to read it an find out what is says... However you should not catch the exception in this method. It is better to abort whatever the program was doing. Catch it in your main method - just printing or logging it is fine, so that you can correct the programming error.
Anyway; The result you get is a List of user entries. Lists are part of the (java.util)collections framework. Collections have a lot of features; in this case you want to iterate over all entries in the list. You can do this by using the iterator() method -read the javadoc...OR you can use for-loop syntactic sugar for doing this:
for( UserEntry user : entries ) {
// user is the current UserEntry
System.out.println(user.getTitle().getPlainText());
}
The variables i3 and rn are no good... They shouldn't be class variables, and if you need "temporary" variables, define them close to where you are going to use them.
As for naming of variables, a name like "entry" is less useful than "user". Actually a class called UserEntry should probably be called just User, but I don't know about this API, so...

Categories

Resources