This code takes in users and movies from two separate files and computes a user score for a movie. When I run the code I get the following error:
Exception in thread "main" java.lang.NullPointerException
at RecommenderSystem.makeRecommendation(RecommenderSystem.java:75)
at RecommenderSystem.main(RecommenderSystem.java:24)
I believe the NullPointerException is due to an error in this particular class but I can't spot it. Any thoughts?
import java.io.*;
import java.lang.Math;
public class RecommenderSystem
{
private Movie[] m_movies;
private User[] m_users;
/** Parse the movies and users files, and then run queries against them.
*/
public static void main(String[] argv)
throws FileNotFoundException, ParseError, RecommendationError
{
FileReader movies_fr = new FileReader("C:\\workspace\\Recommender\\src\\IMDBTop10.txt");
FileReader users_fr = new FileReader("C:\\workspace\\Recommender\\src\\IMDBTop10-users.txt");
MovieParser mp = new MovieParser(movies_fr);
UserParser up = new UserParser(users_fr);
Movie[] movies = mp.getMovies();
User[] users = up.getUsers();
RecommenderSystem rs = new RecommenderSystem(movies, users);
System.out.println("Alice would rate \"The Shawshank Redemption\" with at least a "
+ rs.makeRecommendation("The Shawshank Redemption", "asmith"));
System.out.println("Carol would rate \"The Dark Knight\" with at least a "
+ rs.makeRecommendation("The Dark Knight", "cd0"));
}
/** Instantiate a recommender system.
*
* #param movies An array of Movie that will be copied into m_movies.
* #param users An array of User that will be copied into m_users.
*/
public RecommenderSystem(Movie[] movies, User[] users)
throws RecommendationError
{
m_movies = movies;
m_users = users;
}
/** Suggest what the user with "username" would rate "movieTitle".
*
* #param movieTitle The movie for which a recommendation is made.
* #param username The user for whom the recommendation is made.
*/
public double makeRecommendation(String movieTitle, String username)
throws RecommendationError
{
int userNumber;
int movieNumber;
int j=0;
double weightAvNum =0;
double weightAvDen=0;
for (userNumber = 0; userNumber < m_users.length; ++userNumber)
{
if (m_users[userNumber].getUsername().equals(username))
{
break;
}
}
for (movieNumber = 0; movieNumber < m_movies.length; ++movieNumber)
{
if (m_movies[movieNumber].getTitle().equals(movieTitle))
{
break;
}
}
// Use the weighted average algorithm here (don't forget to check for
// errors).
while(j<m_users.length){
if(j!=userNumber){
weightAvNum = weightAvNum + (m_users[j].getRating(movieNumber)- m_users[j].getAverageRating())*(m_users[userNumber].similarityTo(m_users[j]));
weightAvDen = weightAvDen + (m_users[userNumber].similarityTo(m_users[j]));
}
j++;
}
return (m_users[userNumber].getAverageRating()+ (weightAvNum/weightAvDen));
}
}
class RecommendationError extends Exception
{
/** An error for when something goes wrong in the recommendation process.
*
* #param s A string describing the error.
*/
public RecommendationError(String s)
{
super(s);
}
}
If the file you posted is unaltered from the file that generated the stack trace you posted, then the nullpointer exception on line 75 is somewhere in this code:
weightAvNum = weightAvNum + (m_users[j].getRating(movieNumber)- m_users[j].getAverageRating())*(m_users[userNumber].similarityTo(m_users[j]));
So since m_users is not null (otherwise it would have crashed earlier) either m_users[j] or m_users[userNumber] is null, i.e., there is some null element in the m_users array.
Related
I am writing a Java program by using the Binance JAVA API to retrieve the 1-minute interval candelsticks of a trading pair. Using this Java class, I want to calculate the EMA (Exponential Moving Average) of the past 10 days.
The Binance JAVA API websocket implementation gets the latest depth events, which also contains the current closing price that I use to update the EMA calculation by calling the EMA#update method.
However, I notice that the EMA showing on the Binance's graph, does not correspond to the ones I get from my code. Also, I notice that the values need some time to 'settle' before giving (somewhat) same values compared to those shown on Binance.
On TradingView I found a formula to calculate the EMA (that shows the same EMA value as on Binance), but that is different than the one used in the EMA class. However, even when using this formula, the values are very different than the one on Binance.
Could someone help me figure out what the issue is and how to obtain the same values?
UPDATE 1: code provided
import java.util.*;
import java.util.stream.Collectors;
import com.binance.api.client.BinanceApiClientFactory;
import com.binance.api.client.BinanceApiRestClient;
import com.binance.api.client.BinanceApiWebSocketClient;
import com.binance.api.client.domain.market.Candlestick;
import com.binance.api.client.domain.market.CandlestickInterval;
import core.util.text.DecimalFormat;
import core.util.text.StringUtil;
public class test_003
{
private Map<Long, Candlestick> candlesticksCache = new TreeMap<>();
private EMA EMA_10;
private EMA EMA_20;
public static void main(String[] pArgs)
{
new test_003();
}
private test_003()
{
Locale.setDefault(Locale.US);
candlesticksCacheExample("ADAUSDT", CandlestickInterval.ONE_MINUTE);
}
private void candlesticksCacheExample(String symbol, CandlestickInterval interval)
{
initializeCandlestickCache(symbol, interval);
startCandlestickEventStreaming(symbol, interval);
}
private void initializeCandlestickCache(String symbol, CandlestickInterval interval)
{
BinanceApiClientFactory factory = BinanceApiClientFactory.newInstance();
BinanceApiRestClient client = factory.newRestClient();
List<Candlestick> candlestickBars_10 = client.getCandlestickBars(symbol.toUpperCase(), interval, Integer.valueOf(11), null, null);
List<Candlestick> candlestickBars_20 = client.getCandlestickBars(symbol.toUpperCase(), interval, Integer.valueOf(21), null, null);
List<Double> closingPriceList_10 = candlestickBars_10.stream().map(c -> Double.valueOf(c.getClose())).collect(Collectors.toList());
List<Double> closingPriceList_20 = candlestickBars_20.stream().map(c -> Double.valueOf(c.getClose())).collect(Collectors.toList());
EMA_10 = new EMA(closingPriceList_10, Integer.valueOf(10));
EMA_20 = new EMA(closingPriceList_20, Integer.valueOf(20));
}
private void startCandlestickEventStreaming(String symbol, CandlestickInterval interval)
{
BinanceApiClientFactory factory = BinanceApiClientFactory.newInstance();
BinanceApiWebSocketClient client = factory.newWebSocketClient();
client.onCandlestickEvent(symbol.toLowerCase(), interval, response -> {
Long openTime = response.getOpenTime();
Candlestick updateCandlestick = candlesticksCache.get(openTime);
if (updateCandlestick == null)
{
// new candlestick
updateCandlestick = new Candlestick();
}
// update candlestick with the stream data
updateCandlestick.setOpenTime(response.getOpenTime());
updateCandlestick.setOpen(response.getOpen());
updateCandlestick.setLow(response.getLow());
updateCandlestick.setHigh(response.getHigh());
updateCandlestick.setClose(response.getClose());
updateCandlestick.setCloseTime(response.getCloseTime());
updateCandlestick.setVolume(response.getVolume());
updateCandlestick.setNumberOfTrades(response.getNumberOfTrades());
updateCandlestick.setQuoteAssetVolume(response.getQuoteAssetVolume());
updateCandlestick.setTakerBuyQuoteAssetVolume(response.getTakerBuyQuoteAssetVolume());
updateCandlestick.setTakerBuyBaseAssetVolume(response.getTakerBuyQuoteAssetVolume());
// Store the updated candlestick in the cache
candlesticksCache.put(openTime, updateCandlestick);
double closingPrice = Double.valueOf(updateCandlestick.getClose());
EMA_10.update(closingPrice);
EMA_20.update(closingPrice);
System.out.println(StringUtil.replacePlaceholders("Closing price: %1 | EMA(10): %2 - EMA(20): %3", response.getClose(),
DecimalFormat.format(EMA_10.get(), "#.#####"),
DecimalFormat.format(EMA_20.get(), "#.#####")));
});
}
public class EMA
{
private double currentEMA;
private final int period;
private final double multiplier;
private final List<Double> EMAhistory;
private final boolean historyNeeded;
private String fileName;
public EMA(List<Double> closingPrices, int period)
{
this(closingPrices, period, false);
}
public EMA(List<Double> closingPrices, int period, boolean historyNeeded)
{
currentEMA = 0;
this.period = period;
this.historyNeeded = historyNeeded;
this.multiplier = 2.0 / (double) (period + 1);
this.EMAhistory = new ArrayList<>();
init(closingPrices);
}
public double get()
{
return currentEMA;
}
public double getTemp(double newPrice)
{
return (newPrice - currentEMA) * multiplier + currentEMA;
}
public void init(List<Double> closingPrices)
{
if (period > closingPrices.size()) return;
//Initial SMA
for (int i = 0; i < period; i++)
{
currentEMA += closingPrices.get(i);
}
currentEMA = currentEMA / (double) period;
if (historyNeeded) EMAhistory.add(currentEMA);
//Dont use latest unclosed candle;
for (int i = period; i < closingPrices.size() - 1; i++)
{
update(closingPrices.get(i));
}
}
public void update(double newPrice)
{
// EMA = (Close - EMA(previousBar)) * multiplier + EMA(previousBar)
currentEMA = (newPrice - currentEMA) * multiplier + currentEMA;
if (historyNeeded) EMAhistory.add(currentEMA);
}
public int check(double newPrice)
{
return 0;
}
public String getExplanation()
{
return null;
}
public List<Double> getEMAhistory()
{
return EMAhistory;
}
public int getPeriod()
{
return period;
}
}
}
UPDATE 2
The problem is that onCandlestickEvent is not just called when a candle is completed, but actually multiple times per minute (every 2 seconds or so). The data that you are receiving in the response spans the time from when the candle is opened until the event time of the response, whether the candle is completed or not.
To see what I mean, you could replace the System.out() statement in your startCandlestickEventStreaming method with the following:
System.out.println(response.getOpenTime() + ";" +
response.getEventTime() + ";" +
response.getCloseTime());
You will see that the close time of the candle actually lies in the future.
In order to update your EMA correctly, you will have to wait until the candle has actually been completed. You could store the open time of the tentative candle in a member variable, check if it has changed since the last time onCandlestickEvent was called, and then update your EMA with the final close value of the candle:
client.onCandlestickEvent(symbol.toLowerCase(), interval, response -> {
Long openTime = response.getOpenTime();
Candlestick updateCandlestick = candlesticksCache.get(openTime);
if (updateCandlestick == null)
{
// new candlestick
updateCandlestick = new Candlestick();
}
// update candlestick with the stream data
...
// Store the updated candlestick in the cache
candlesticksCache.put(openTime, updateCandlestick);
if (openTime > m_LastOpenTime)
{
// need to get the close of the PREVIOUS candle
Candlestick previousCandle = candlesticksCache.get(m_LastOpenTime);
double closingPrice = Double.valueOf(previousCandle.getClose());
EMA_10.update(closingPrice);
EMA_20.update(closingPrice);
System.out.println(StringUtil.replacePlaceholders("Closing price: %1 | EMA(10): %2 - EMA(20): %3", response.getClose(),
DecimalFormat.format(EMA_10.get(), "#.#####"),
DecimalFormat.format(EMA_20.get(), "#.#####")));
m_LastOpenTime = openTime;
}
});
You'll probably get an exception on the first response, because there are no candles on the stack yet and we don't have a m_LastOpenTime. You could get the current server time before calling client.onCandlestickEvent():
private void startCandlestickEventStreaming(String symbol, CandlestickInterval interval)
{
BinanceApiClientFactory factory = BinanceApiClientFactory.newInstance();
BinanceApiWebSocketClient client = factory.newWebSocketClient();
BinanceApiRestClient restClient = factory.newRestClient();
m_LastOpenTime = restClient.getServerTime();
client.onCandlestickEvent(symbol.toLowerCase(), interval, response -> {
...
}
}
I noticed there's actually a much simpler way than my other answer. I'm leaving that one up, however, because it could still be relevant for dealing with a dodgy connection where you can't necessarily rely on always getting the final candlestick with your response.
The response.getBarFinal()) method allows for testing whether the response you have received is the final candlestick or if it is just an intermediate one. If you change your code as follows, your EMA will only get updated with the final close value of the candle as it should be:
if (response.getBarFinal())
{
double closingPrice = Double.valueOf(updateCandlestick.getClose());
EMA_10.update(closingPrice);
EMA_20.update(closingPrice);
System.out.println(StringUtil.replacePlaceholders("Closing price: %1 | EMA(10): %2 - EMA(20): %3", response.getClose(),
DecimalFormat.format(EMA_10.get(), "#.#####"),
DecimalFormat.format(EMA_20.get(), "#.#####")));
}
I have an assignment where I have to read data from a text file. The data looks like this in the file:
1946-01-01;07:00:00;-1.8;G
1946-01-01;13:00:00;-1.0;G
1946-01-01;18:00:00;-1.9;G
1946-01-02;07:00:00;-1.7;G
I want to format the data and put it in an appropriate data structure so that I then can search for average temperature for all dates between two dates. What is the simplest way to format this data when my code is:
package algo.weatherdata;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.time.LocalDate;
import java.util.List;
/**
* Provides methods to retrieve temperature data from a weather station file.
*/
public class WeatherDataHandler {
/**
* Load weather data from file.
*
* #param filePath path to file with weather data
* #throws IOException if there is a problem while reading the file
*/
public void loadData(String filePath) throws IOException {
//Read all weather data
List<String> fileData = Files.readAllLines(Paths.get(filePath));
/**
* TODO: Format data and put it in appropriate data structure.
*/
}
You can iterate over your lines and separate each line by a delimiter (in your case ;):
public void loadData(String filePath) throws IOException {
List<String> fileData = Files.readAllLines(Paths.get(filePath));
String[] lineValues = str.split(";");
// line values are stored in this array
}
Then you can do with the array as you like (store them, process them).
Let's assume the following class that will contain weather data:
public class WeatherData {
private LocalDateTime dateTime;
private double temperature;
private String tag; // I don't really know what is 'G' mean
public WeatherData(LocalDateTime dateTime, double temperature, String tag) {
this.dateTime = dateTime;
this.temperature = temperature;
this.tag = tag;
}
}
Next, we analyze the data file into the current structure and collect them all into a list:
private List<WeatherData> weatherData = new ArrayList<>();
public void loadData(String filePath) throws IOException {
List<String> fileData = Files.readAllLines(Paths.get(filePath));
for(String str : fileData) {
List<String> parsed = parseData(str);
LocalDateTime dateTime = LocalDateTime.of(dateOf(parsed.get(0)),
timeOf(parsed.get(1)));
double temperature = Double.parseDouble(parsed.get(2));
String tag = parsed.get(3);
WeatherData weather = new WeatherData(dateTime, temperature, tag);
weatherData.add(weather);
}
}
private List<String> parseData(String s) {
return Arrays.asList(s.split(";"));
}
private LocalDate dateOf(String date) {
return LocalDate.parse(date);
}
private LocalTime timeOf(String time) {
return LocalTime.parse(time);
}
And then you could work with a list to search between dates and calculate the average temperature
I have tried above Dinar Zaripov piece of code in my work space with addition of generating getters methods for dateTime, temperature and tag.
Continuation after for loop
private static float averageTemperature(List<WeaterData> weatherData)
{
float sum = 0; // Variable to store the sum
float count = 0; // Variable to keep the count
if (weatherList != null) {
for (WeaterData averageWeather : weatherData) {
float value = averageWeather.getTemperature();
System.out.println(value);
if (value <= 0) { // Check if the number is negative
sum += value; // Add the value to the current sum
count++; // Increment the count by 1
}
}
}
return (count > 0) ? (sum /count) : 0; // Calculate the average if there were any negative numbers
}
But I am getting average as ** average::1.5999999 **
However as per the math it should be 1.6. could someone tell me how ? or this is correct ?
when I give below data , I am getting correct average :)
1946-01-01;07:00:00;-1.8;A
** 1946-01-01;13:00:00;-1.1; B**
1946-01-01;18:00:00;-1.9;C
1946-01-02;07:00:00;-1.7;D
I'm testing this class
/**
* Class to classify irises based on petal and sepal measurements.
*
* #author James Howard <jh#jameshoward.us>
*/
package us.jameshoward.iristypes;
import java.io.InputStream;
import java.util.Dictionary;
import java.util.Enumeration;
import weka.classifiers.Classifier;
import weka.core.Attribute;
import weka.core.FastVector;
import weka.core.Instance;
import weka.core.Instances;
import weka.core.SerializationHelper;
public class Iris {
private Classifier classModel;
private Instances dataModel;
private String classModelFile = "/Irises/etc/iris.model";
/**
* Class constructor.
*/
public Iris() throws Exception {
InputStream classModelStream;
// Create a stream object for the model file embedded
// within the JAR file.
classModelStream = getClass().getResourceAsStream(classModelFile);
classModel = (Classifier)SerializationHelper.read(classModelStream) ;
}
/**
* Close the instance by setting both the model file string and
* the model object itself to null. When the garbage collector
* runs, this should make clean up simpler. However, the garbage
* collector is not called synchronously since that should be
* managed by the larger execution environment.
*/
public void close() {
classModel = null;
classModelFile = null;
}
/**
* Evaluate the model on the data provided by #param measures.
* This returns a string with the species name.
*
* #param measures object with petal and sepal measurements
* #return string with the species name
* #throws Exception
*/
public String classifySpecies(Dictionary<String, String> measures) throws Exception {
#SuppressWarnings("rawtypes")
FastVector dataClasses = new FastVector();
FastVector dataAttribs = new FastVector();
Attribute species;
double values[] = new double[measures.size() + 1];
int i = 0, maxIndex = 0;
// Assemble the potential species options.
dataClasses.addElement("setosa");
dataClasses.addElement("versicolor");
dataClasses.addElement("virginica");
species = new Attribute("species", dataClasses);
// Create the object to classify on.
for (Enumeration<String> keys = measures.keys(); keys.hasMoreElements(); ) {
String key = keys.nextElement();
double val = Double.parseDouble(measures.get(key));
dataAttribs.addElement(new Attribute(key));
values[i++] = val;
}
dataAttribs.addElement(species);
dataModel = new Instances("classify", dataAttribs, 0);
dataModel.setClass(species);
dataModel.add(new Instance(1, values));
dataModel.instance(0).setClassMissing();
// Find the class with the highest estimated likelihood
double cl[] = classModel.distributionForInstance(dataModel.instance(0));
for(i = 0; i < cl.length; i++)
if(cl[i] > cl[maxIndex])
maxIndex = i;
return dataModel.classAttribute().value(maxIndex);
}
}
when start initialising its instance from another class with
Iris irisModel = new Iris();
i got following error
Exception in thread "main" java.io.IOException: Stream closed
at java.io.BufferedInputStream.getInIfOpen(BufferedInputStream.java:159)
at java.io.BufferedInputStream.fill(BufferedInputStream.java:246)
at java.io.BufferedInputStream.read1(BufferedInputStream.java:286)
at java.io.BufferedInputStream.read(BufferedInputStream.java:345)
at java.io.ObjectInputStream$PeekInputStream.read(ObjectInputStream.java:2320)
at java.io.ObjectInputStream$PeekInputStream.readFully(ObjectInputStream.java:2333)
at java.io.ObjectInputStream$BlockDataInputStream.readShort(ObjectInputStream.java:2804)
at java.io.ObjectInputStream.readStreamHeader(ObjectInputStream.java:802)
at java.io.ObjectInputStream.<init>(ObjectInputStream.java:299)
at weka.core.SerializationHelper.read(SerializationHelper.java:288)
at us.jameshoward.iristypes.Iris.<init>(Iris.java:33)
at us.jameshoward.iristypes.IrisDriver.main(IrisDriver.java:11)
I guess this error is case specific, by comparing with other posts, i still cant find out where it went wrong. in fact, this class was downloaded from IBMknowledge website, it supposes to be error-proof i guess.
anyone knows how to fix this?
thanks
I am struggling to read this stack trace exception below. I wonder If you could help me?
I don't understand any of the numbers in the code (like the number 74, 2119 and 2160, what do they represent in this exception? Quite literally, I need to know which line of my code is causing problems so that I can resolve it. Please help.
Here below is my stack trace, and beneath it is the java code I am trying to resolve alongside a sample input file which came with the task.
java.util.InputMismatchException
in java.util.Scanner.throwFor(Scanner.java:909)
in java.util.Scanner.next(Scanner.java:1530)
in java.util.Scanner.nextInt(Scanner.java:2160)
in java.util.Scanner.nextInt(Scanner.java:2119)
in League.loadLeague(League.java:74)
in (Workspace:1)
And here, below is my Java code with the method loadLeague which is causing me a lot of headache!
import java.io.*;
import java.util.*;
/**
* Class League - An instance of this class represents the teams in a
* football (or similar) league. It provides a class method for creating
* a new instance of League by reading the data for the teams from a CSV
* file.
*
* #author Lewis Jones
* #version 1.0
*/
public class League
{
/* instance variables */
private String name; // The name of the league
private Team[] teams; // An array to hold the teams in the league
/**
* Constructor for objects of class League. It sets the name of the league
* to the String object provided as the first argument and initialises teams
* to an array of the size provided as the second argument. This constructor
* is private as it is intended for use only by the class method loadLeague().
*/
private League(String aName, int size)
{
super();
this.name = aName;
this.teams = new Team[size];
}
/* class method */
/**
* This method creates a new League object by reading the required details from
* a CSV file. The file must be organised as follows:
* name(String), number of teams (int)
* team name(String), won(int), drawn(int), lost(int), for(int), against (int)
* and so on for each team
* Having created the new League object the method should create all the Team
* objects (using the data in the file to set their attributes) and add them
* to the teams array.
*/
public static League loadLeague()
{
League theLeague = null;
String pathname = OUFileChooser.getFilename();
File aFile = new File(pathname);
Scanner bufferedScanner = null;
try
{
String leagueName;
int numberOfTeams;
String teamName;
int won;
int drawn;
int lost;
int goalsFor;
int goalsAgainst;
Scanner lineScanner;
String currentLine;
bufferedScanner = new Scanner(new BufferedReader(new FileReader (aFile)));
while (bufferedScanner.hasNextLine())
{
currentLine = bufferedScanner.nextLine();
lineScanner = new Scanner(currentLine);
lineScanner.useDelimiter(",");
leagueName = bufferedScanner.next();
numberOfTeams = bufferedScanner.nextInt();
teamName = bufferedScanner.next();
won = lineScanner.nextInt();
drawn = lineScanner.nextInt();
lost = lineScanner.nextInt();
goalsFor = lineScanner.nextInt();
goalsAgainst = lineScanner.nextInt();
Team aTeam = new Team(lineScanner.next());
aTeam.setWon(lineScanner.nextInt());
aTeam.setDrawn(lineScanner.nextInt());
aTeam.setLost(lineScanner.nextInt());
aTeam.setGoalsFor(lineScanner.nextInt());
aTeam.setGoalsAgainst(lineScanner.nextInt());
Team[] teams = new Team[numberOfTeams];
teams[numberOfTeams] = aTeam;
numberOfTeams++;
theLeague = new League(leagueName, numberOfTeams);
}
}
catch (Exception anException)
{
System.out.println("Error: " + anException);
}
finally
{
try
{
bufferedScanner.close();
}
catch (Exception anException)
{
System.out.println("Error: " + anException);
}
}
return theLeague;
}
/* instance methods */
/**
* Displays the league table in tabular format to the standard output
*/
public void display()
{
System.out.println(this.name);
System.out.format("%20s %2s %2s %2s %2s %2s %2s % 2s\n","","P","W","L","D","F","A","Pt");
for (Team eachTeam : this.teams)
{
System.out.format("%20s %2d %2d %2d %2d %2d %2d %2d\n",
eachTeam.getName(), eachTeam.getPlayed(),
eachTeam.getWon(), eachTeam.getDrawn(),
eachTeam.getLost(),eachTeam.getGoalsFor(),
eachTeam.getGoalsAgainst(), eachTeam.getPoints());
}
}
/**
* Arrange the elements of teams in their natural order. This will only
* work if a natural order has been defined for the class Team.
*/
public void sort()
{
// to be written later...
}
}
And below is the sample (file) input which the program is supposed to read into:
Scottish League Division 1,10
Airdrie United ,3,2,11,14,25
Clyde ,5,7,4,21,17
Dundee ,7,2,7,21,18
Gretna ,10,3,3,43,20
Hamilton Acas ,7,5,4,19,20
Livingstone ,6,6,4,21,15
Partick Thistle,8,4,4,25,29
Queen of South ,3,3,10,11,31
Ross County ,4,4,8,14,24
St Johnstone ,6,6,4,26,16
I have really struggled with this task for nearly a week now! I hope someone out there comes to my rescue as it's really getting on my skin now. Please help. Any tips to pinpoint which code I'm writing wrongly would be so much appreciated.
Thank you guys,
Lew.
Those numbers (74, 2119 and 2160) are the code lines. The top most line of the stack trace is where the actual error occurred, and the rest are the call locations in the stack trace.
So in this event, Scanner.java:909 means that the error occurred at line 909 of the Scanner class, which was in a function called at line 1530 in Scanner, and so on and so forth.
This code works, but with a try/catch box .
public enum AccentuationUTF8 {/** */
é, /** */è, /** */ç, /** */à, /** */ù, /** */
ä, /** */ë, /** */ö, /** */ï, /** */ü, /** */
â, /** */ê, /** */î, /** */ô, /** */û, /** */
}
......
final EnumSet<AccentuationUTF8> esUtf8 = EnumSet.noneOf(AccentuationUTF8.class);
final String[] acc1 = {"é", "à", "u"};
for (final String string : acc1) {
try { // The ontologic problem
esUtf8.add(AccentuationUTF8.valueOf(string));
} catch (final Exception e) {
System.out.println(string + " not an accent.");
}
}
System.out.println(esUtf8.size() + "\t" + esUtf8.toString()
output :
u not an accent.
2 [é, à]
I want to generate an EnumSet with all accents of a word or of sentence.
Edit after comments
Is it possible to manage such an EnumSet without using try (needed by AccentuationUTF8.valueOf(string)?
Is better way to code ?
FINAL EDIT
Your responses suggest me a good solution : because EnumSet.contains(Object), throw an Exception, change it : create a temporary HashSet able to return a null without Exception.
So the ugly try/catch is now removed, code is now :
final Set<String> setTmp = new HashSet<>(AccentsUTF8.values().length);
for (final AccentsUTF8 object : AccentsUTF8.values()) {
setTmp.add(object.toString());
}
final EnumSet<AccentsUTF8> esUtf8 = EnumSet.noneOf(AccentsUTF8.class);
final String[] acc1 = {"é", "à", "u"};
for (final String string : acc1) {
if (setTmp.contains(string)) {
esUtf8.add(AccentsUTF8.valueOf(string));
} else {
System.out.println(string + " not an accent.");
}
}
System.out.println(esUtf8.size() + "\t" + esUtf8.toString()
Thanks for attention you paid for.
I don't think an enum is the best approach here - partly because it's only going to work for valid Java identifiers.
It looks like what you really want is just a Set<Character>, with something like:
Set<Character> accentsInText = new HashSet<Character>();
for (int i = 0; i < text.length(); i++) {
Character c = text.charAt(i);
if (ALL_ACCENTS.contains(c)) {
accentsInText.add(c);
}
}