i am facing a problem which is:
I have map containing string and string. When i print that map i can see that there is a key
"0-8166-3835-7". But when i am trying to get it, there is nothing to get returned, like no matching found...
My code:
//Open a stream to read from file with isbn's AND titles
Scanner IsbnTitle = new Scanner(new FileReader("C:/Users/Proskopos/Documents/NetBeansProjects/ReadUrl/IsbnTitle.txt"));
//Create a Map to save both ISBN's and Titles
Map <String,String> IsbnTitleMap = new HashMap();
while(IsbnTitle.hasNext()){
String recordIsbnTitle = IsbnTitle.nextLine();
UrlFunctions.AddToMap(Recognised , recordIsbnTitle, IsbnTitleMap);
}
.....
.....
Set IsbnSet = new HashSet();
while (IsbnFile.hasNextLine()) {
String isbn = IsbnFile.nextLine();
IsbnSet.add(isbn);
}
//Create an Iterator for IsbnSet
Iterator IsbnIt =IsbnSet.iterator();
String suffix = IsbnIt.next().toString();
String OPACIALtitle = UrlFunctions.GetOpacTitle(suffix, IsbnTitleMap);
The code above is the only part in main about MAP and below are the functions i call:
static String GetOpacTitle(String opIsbn, Map IsbnTitle) {
String OpacTitle = null;
String isbn = opIsbn;
Map isbnMap = IsbnTitle;
System.out.println(isbn);
if ( isbnMap.containsKey(isbn)){
System.out.println("AAAAAAAAAAAAAAAA");
}
//String tade = isbnMap.get(isbn).toString();
//System.out.println("*************" + tade);
return OpacTitle;
}
static void AddToMap(int Recognise, String recordIsbnfollowed, Map IsbnfollowedMap) {
Map isbnsth = IsbnfollowedMap;
String records = recordIsbnfollowed;
int recs= Recognise;
if (recs == 0 || recs == 3) {
String isbn = records.substring(0, 10);
String title = records.substring(10);
isbnsth.put(isbn, title);
// System.out.println(isbn);
}else if (recs == 1) {
String isbn = records.substring(0, 14);
String title = records.substring(14);
isbnsth.put(isbn, title);
// System.out.println(isbn);
}
}
I cant understand where the problem is.. Maybe it is something like encoding of the suffix cames from a set, and the key from a map? they are both string.. dont think so..!!!
So? Can you help?
EDIT: I am trully sorry if you find the code difficult to read :\ I will follow your advices!!
BUT in case that anyone else has the same problem the solution was what Brand said below.. (I re-post it)
You probably have some whitespace in the Strings that you are reading form the file and storing in the Map. If this is the case use String.trim() before storing the value in the Map, and also before querying for the same string. – Brad 3 hours ago
Thank you all
Just to add to my comment that identified the problem. When comparing Keys in a Map you must be very careful about white space and case sensitivity. These types of issues commonly occure when reading data from Files because it's not always obvious what characters are being read. Even looking in your debugger whitepsace cna be an issue.
Always try to "normalize" your data by trimming leading and trailing whitespace before storing it in a Map.
Related
I have a text file, which is filled with many lines of code in the layout: "fiesta, ford". I read these lines with new BufferedReader(new InputStreamReader(...)) and then I display them in my app.
This method findCar() takes an input, compares it with the keys of the hashmap which are taken from the text file, and if it matches, it displays the car model and the card brand in another layout part :). What is for example: Is there a possibility to make my code a little more advanced? Let's say that the user types Fiesta 2018, or Fiesta 2019. I want it to be accepted. So I want to say that if the given string contains "Fiesta", match it with "ford" and display them. I don't know how to make it work for every other brand, and i don't want to have 100 if statements.
I am sorry for the rookie question, I have tried many many versions like else if(car.equalsIgnoreCase(carItem.getKey())){ but I can't make it work.
public String findCar(String car) {
String x = "";
for (HashMap.Entry<String, String> carItem: itemsMap.entrySet()) {
if (carItem.getKey().equalsIgnoreCase(car)){
x = x + "Found " + carItem.getKey() + " in:" + carItem.getValue();
return x;
}
}
return "Sorry, not found :D";}
You should try following code (use "contains" function and convert to one case both strings) :
public String findCar(String car) {
String carLowerCase = car.toLowerCase().trim();
String x = "";
for (HashMap.Entry<String, String> carItem: itemsMap.entrySet()) {
String key = carItem.getKey().toLowerCase().trim();
if (carLowerCase.contains(key)){
x = x + "Found " + carItem.getKey() + " in:" + carItem.getValue();
return x;
}
}
return "Sorry, not found :D";
}
You want to refine your keyword.
For example, in the
Fiesta 2018
you only need the Fiesta part. So it makes sense say if the last four letters are digits, you simply remove it.
For example:
Map<String,String> modelBrand = new HashMap<>();
String keyword = "Fiesta 2018";
String[] keys = keyword.split(" [0-9]{4}");
if(keys.length > 0) {
keyword = keys[0];
}
// Print not found since nothing in the map.
System.out.println(modelBrand.getOrDefault(keyword.toLowerCase(), "Not found"));
modelBrand.put("fiesta", "ford");
// Print ford as it finds the fiesta keyword.
System.out.println(modelBrand.getOrDefault(keyword.toLowerCase(), "Not found"));
A better way to do it is utilize a search engine, such as the open source solr.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 7 years ago.
Improve this question
Lets say we have,
String value = "{name = abc, address = xyz, abc, school = mno}"
How can we convert this string into a Map as we split the key value pair of the string with comma? Here when I try to split with comma I get an error saying no value for key abc as address = xyz acts as a key value pair.
Any generic approach will be greatly appreciated.
From what I understand, you want to create a map in which the entry with the key address has xyz, abc as value.
You can use regex for this. Here is an example:
String s = "{name = abc, address = xyz, abc, school = mno}";
HashMap<String, String> map = new HashMap<String, String>();
for (String element : s.replaceAll("[{}]", "").split("(,(?=[^,]+=))")) {
String[] entry = element.split("=");
map.put(entry[0].trim(), entry[1].trim());
}
What this does is to first remove all { and } character from the String and split that String on every , that is followed by a sequence of characters that doesn't contain a , and ends in a = character.
I have written a function which should solve your problem.
Maybe your IDE shows some syntax errors, if so, you have to corrent them yourself. I used Notepad in this example.
Here are a few steps to get the result you want, followed by the code:
Remove the brackets
Split the string by each comma ","
Split every single resulting String again by the equal sign "="
Put the first Array index as key and second Array index as value into your map.
(optional) call .trim() on the Array indices first to remove white spaces.
So here is an example function:
public void ParseToMap(String data, Map<String, String> map)
{
//Make sure we don't run into trouble
if(data == null || data.isEmpty() || map == null)
{
return;
}
// Splits by ','
String[] keyValuePairs = data.substring(1,data.length()-2).split(",");
for(int i = 0; i < keyValuePairs.length(); i++)
{
// Splits by '='
String _tmp = keyValuePairs[i].split("=");
if(_tmp.length() > 1)
{
String key = _tmp[0].trim(); // Get the key + remove useless spaces
String value = _tmp[1].trim(); // Get the value + remove useless spaces
map.put(key, value); // Insert the pair
}
}
}
As other said in comments, you should be using a JSON parser to handle this.
With that said, we can still provide some code that will be able to handle your example string (but would most likely fail for some other examples) :
String value = "{name = abc, address = xyz, abc, school = mno}";
Map<String, String> result = new HashMap<>();
String[] parts = value.replaceAll("[{}]", "").split(",");
for (String part : parts) {
String[] operands = part.split("=");
if (operands.length == 2) { // we have a x = y pattern
result.put(operands[0].trim(), operands[1].trim());
}
}
You can split your String in two level to get the key/value couple :
String value = "name = abc, address = xyz, abc, school = mno";
Map<String, String> map = new HashMap<String, String>();
String [] values = value.split(", ");
for (String couple : values){
if(couple.contains(" = ")) {
String [] subValues = couple.split(" = ");
map.put(subValues[0], subValues[1]);
}else{
map.put(couple, null);
}
}
Note : you should get rid of the brackets {} in your String value before
I've got a question about making a save function.
I'm trying to have a string be saved as a single file to set specific settings on a game. So saveFile would read "002007...", having 002 be a player's location, then 007 a player's level, for example.
I understand how to compile the various variables into a single string, but how would I return it to individual variables?
You better go with SQLite or SharedPreferences if you really want to save settings for a game on Android.
On the other hand, if you have to stick with saving a String on a file, you might want to use a delimiter(ie \r\n or # or | would do it) between numbers. So while parsing back delimiters will help you a lot, but beware when things get complicated a single String won't do the thing nicely. Then you might want to use JSON (for simplicity I would prefer gson) to encode your settings into one String and vice verse.
You could use a delimiter between the values like this:
int location = 02;
int level = 3;
int powerUps = 46;
... and so on
String saveString = location + "#" + level + "#" + powerUps + "#" + ...
Then to load the String back into variables:
String[] values = saveString.split("#");
location = values[0];
level = values[1];
powerUps = values[2];
... and so on
My advice is to check out Shared Preferences and you can read Android's documentation on it here.
If you did want to use your single String, file method, I suggest using delimiters. That simply means to put commas, or other types of delimeters in between different integer values. Instead of "002007", save it as "002,007". Example:
String s = "002,007"
String[] values = s.split(","); // values[0] is "002" and values[1] is "007"
Using the .split(String) command will return a String array with each element in the array containing parts of the String that was split up by the parameter, in this case: ,
If you wanted to separate values per person, something like this could be done:
String s = "002,007;003,008";
String[] people = s.split(";"); // people[0] is "002,007", people[1] is "003,004"
String[][] person = new String[people.length][people[0].split(",").length];
for (int i = 0; i < people.length; i++)
{
person[i] = people[i].split(",");
}
Here is what the array would then contain:
person[0][0] is "002"person[0][1] is "007" person[1][0] is "003" person[1][1] is "008"
// print it for your own testing
for (String ppl[] : person)
{
for (String val : ppl)
{
System.out.print(val + " ");
}
System.out.println("");
}
I'm a beginner programmer and I'm trying to do one program that opens a text file with a large text inside and then it counts how many words it contains.
Then it should write how many different words are in the text, and write the frecuency of each word in the text.
I had the intention to use one array-string to store all unique words and one int-string to store the frequency.
The program counts the words, but I'm a little bit unsure about how could I write the code correctly to get the list of the words and the frequency them are repeated in the text.
I wrote this:
import easyIO.*;
import java.util.*;
class Oblig3A{
public static void main(String[] args){
int cont = 0;
In read = new In (alice.txt);
In read2 = new In (alice.txt);
while(read.endOfFile() == false)
{
String info = read.inWord();
System.out.println(info);
cont = cont + 1;
}
System.out.println(UniqueWords);
final int AN_WORDS = cont;
String[] words = new String[AN_WORDS];
int[] frequency = new int[AN_WORDS];
int i = 0;
while(les2.endOfFile() == false){
word[i] = read2.inWord();
i = i + 1;
}
}
}
Ok, here is what you need to do:
1. Use a BufferedReader to read the lines of text from the file, one by one.
2. Create a HashMap<String,Integer> to store the word, frequency relations.
3. When you read each line of text, use split() to get all the words in the line of text in an array of String[]
4. Iterate over each word. For each word, retrieve the value from the HashTable. if you get a null value, you have found the word for the first time. Hence, create a new Integer with value 1 and place it back in the HashMap
If you get a non-null value, then increment the value and place it back in the HashMap.
5. Do this till you do not reach EOF.
Done !
You can use a
Map<String, Integer> map = HashMap<String, Integer>();
And then add the words to the map asking if the value is already there. If it is not, add it to the map with a counter initialized to 1.
if(!map.containsKey(word))
{
map.put(word, new Integer("1"));
}
else
{
map.put(word, map.get(word) + new Integer(1));
}
In the end you will have a map with all the words that the file contains and a Integer that represents how many times does the word appear in the text.
You basically need a hash here. In java , you can use a HashMap<String, Integer> which will store words and their frequency.
So when you read in a new word, check it up in the hashMap, say h, and if it exists , increase the frequency or add a new word with frequency = 1.
If you can use a library you may want to consider using a Guava Multiset, it has the counting functionality already built in:
public void count() throws IOException {
Multiset<String> countSet = HashMultiset.create();
BufferedReader bufferedReader = new BufferedReader(new FileReader("alice.txt"));
String line;
while ((line = bufferedReader.readLine()) != null) {
List<String> words = Arrays.asList(line.split("\\W+"));
countSet.addAll(words);
}
bufferedReader.close();
for (Entry<String> entry : countSet.entrySet()) {
System.out.println("word: " + entry.getElement() + " count: " + entry.getCount());
}
}
I have a text file that contains information formated in a key=value way. How do I look up the key and return the value.
For example, let's say the file has:
KeyOne=ValueOne
KeyTwo=ValueTwo
and I would like to have a method which takes KeyOne and returns ValueOne.
Okay, I'm in a good mood :), untested:
//given that 'input' got the contents of the file
Map<String,String> m = new HashMap<String,String>();
//this can be done more efficient probably but anyway
//normalize all types of line breaks to '\n'
input = input.replaceAll("\r\n","\n");
input = input.replaceAll("\r","\n");
//populate map
String[] lines = input.split("\n");
for(int i=0 ; i< lines.length; i++){
String[] nv = lines[i].split("=");
m.put(nv[0],nv[1]);
}
//get value given key:
String key = "somekey";
String someValue = m.get(key);
System.out.println(someValue);
Scanner s = new Scanner("Filename");
Map<String, String> m = new HashMap<String, String>();
while(s.hasNext()){
String line[] = s.nextLine().split("=");
m.put(line[0], line[1]);
}
To get the value:
m.get(ValueOne);
In case all you need is to read name-value pairs, and if that is of configuration nature, then you can consider using properties file in Java.
You can check this out http://www.mkyong.com/java/java-properties-file-examples/
Whole bunch of ways. You could
a. Read the file once line by line, split the input and then populate a map
b. Apply a regex expression search to the file as a whole
c. You could index a full text search the thing
It all depends on your use case. Hard to recommend an approach without understanding the context.