I am currently making a flash card program, and I want the user to be able to put in their own questions and answers, then test themselves. My only problem is that i want the values they enter to be there permanently until changed by them. How do I do this? (P.S: if you need the code, I can give it.)
I assume that you are new to programming and you have not yet worked with persistence of any context. In this case, for your simple example, the Java Properties class might be a good entry point into the field of file persistence.
In general, there are plenty of ways to persist data: databases, files, web storage, etc... It depends on your application and what you want to do with the data. For an example of the Java Properties file see for example this tutorial: http://www.mkyong.com/java/java-properties-file-examples/
Well without seeing any of the code, it is hard to tell you exactly how you should approach this, but in general you will need some method of persistence to save this type of information, ie. a database, flat file, etc. Try looking into sqlite or even XML for storage and retrieval.
Related
First of all this might be a dumb question and I searched for some days but didn't find an answer. So if there is an existing answer concerning my question, I would be grateful for a link.
I don't know if anyone of you ever coded Spigot, Paper or Bukkit, but there was a class called YamlConfiguration which had the following methods:
public FileConfiguration cfg = YamlConfiguration.loadConfiguration(file);
cfg.set(path.path2, "hello");
cfg.getInt/String/...(path.path2); (which obviously returns "hello")
cfg.save(file);
The produced file then looks like this:
path:
path2: "hello"
So you could basically save any value in those files and reuse them even if your program has been restarted.
I know have moved forward from Spigot/Paper to native Java and I'm missing something like that Yaml-thing. The only thing I found was a kind of a config file, where every time the whole file is overwritten, when I try to add values.
Can you show me a proper way of saving values to a file? (would be nice without libraries)
I'm missing sth like that Yaml-thing
SnakeYAML should have you covered. Without knowing anything about your use-case, it makes no sense to discuss its usage here since its documentation already does cover the general topics.
The only thing I found was a kind of a config file, where everytime the whole file is overwritten, when I try to add values.
Saving as YAML will always overwrite the complete file as well. Serialization does not really work with append-only. (Serialization is the term to search for when you want functionality like this, by the way.)
If you mean that previous values were deleted, that probably was because you didn't load the file's content before or some other coding error, but since you don't show your code, we can only speculate.
Can you show me a proper way of saving values to a file?
People will have quite different opinions on what would be a proper way and therefore it is not a good question to ask here. It also heavily depends on your use-case.
would be nice without libraries
So you're basically saying „previously I used a library which had a nice feature but I want to have that feature without using a library“. This stance won't get you far in today's increasingly modular software world.
For example, JAXB which offers (de)serialization from/to XML was previously part of Java SE, but has been removed as of Java SE 11 and is a separate library now.
I have read many blogs about how singleton are vulnerable in android.so my question is how to maintain such global objects or list in application.i know shared preference is one way but is there any way to maintain such objects or list efficiently.any help will be more helpful.
You can use a file or SQLite database to save data in android app. You can check below links to learn more about saving data in a file or SQLite database:
Saving data to a file is ideal to store long sequences of data that are generally read in order
https://developer.android.com/training/basics/data-storage/files.html
Saving data to a database is ideal for repeating or structured data:
https://developer.android.com/training/basics/data-storage/databases.html
use sharedPreferences, Sqlite database to manage your objects, singletons are not very good, but static variables are more hard to maintain and will make testing the cide more tough, you can use Shared preferences to maintain a global state if the data is not very large, if there is large amount of data then use of sqlite is recommended.
Shared preferences are extremely easy to use, if you have problem using sqlite though you can use orm libraries for android
here's a link to one: http://greenrobot.org/greendao/
If you just want to keep a list as Global until your app is running, then create a new class let's say "Helper" and Initialize a Static List in that class. Now you can access that list anywhere within the app by "Helper.yourStaticListName" and you can also add/remove or get data from the list anywhere within the app.
But if you want to keep that list even when app has been closed, then there are two solutions for that.
First Create a local database "SQLite file" in your app and add/remove or get data from it.
Check this tutorial: http://www.androidhive.info/2011/11/android-sqlite-database-tutorial/
Second solution is to convert your data into a JSON and convert that JSON into String and save it in Shared Preferences. And whenever you need it just get the string from Shared Preferences and convert it into JSON and parse to get the data.
One last thing when you are talking about parsing a JSON, then "GSON library" is a good thing to work with.
Here is the link: http://guides.codepath.com/android/leveraging-the-gson-library
Hope this answer will help you.
How about using Android Service?
You can initialize / start it when your application started (and also stop them when your application stopped) and then bind them whenever you need (put and get your object / list).
I believe it will be an efficient way.
From conceptual point having a static variables or service-locators is very similar to having Singletons. Hence, having them as alternatives may not be be correct, if the intention is to avoid the Global state and consequences.
We can change Singleton-classes into instances, which are instantiated only once and injected into the components and methods as needed. We can use a IoC-framework to handle the injection part or do it manually with a factory pattern to construct (we can restrict only one instance creation as well) instances of the classes. This discussion thread gives lot of insights on the problem and various options.
So if I understand your question right, you need to store some global variables all over your application if that's so please take a look at this question
basically you create a class that extends application which would store anything you would like on start of your app and all of them can be accessed trough out the app.
hope this helps.
If you are trying to create a globally accessible object, the first thing you should ask yourself is: Why? Why do you need a globally accessible object? Most of the time you don't, and you can get away with creating an object with a limited scope which is passed around the app.
There are times when you do want globally accessible resources and using a singleton is just one way to accomplish that. According to the Android Docs your data storage options are:
Shared Preferences
Store private primitive data in key-value pairs.
Internal Storage
Store private data on the device memory.
External Storage
Store public data on the shared external storage.
SQLite Databases
Store structured data in a private database.
Network Connection
Store data on the web with your own network server.
Singletons are great, but the do have their own risks based on how they are implemented. Typically developers use this pattern when you are attempting to share a resource within the application, things like Loggers, Print spoolers, etc. There are multiple ways that you can create Singletons in Java, you can use a Lazy Initialization or Static initialization, each has their own pro/cons. In terms of "vulnerabilities", there are issues with whether or not the singleton is thread-safe, who/what can access it, and so on. This is why it makes sense to try and understand the problem you are trying to solve. Personally, I'm not clear on what exactly you are trying to solve, so I can't really elaborate on how this might help or hurt you. All I can say is that the biggest vulnerability is also it's greatest asset, which is that like most global variables, it can be accessed from anywhere at anytime. There can also be an issue whether or not the singleton is thread-safe.
Personally, I think you need to assess what it is you are trying to solve and the pick the appropriate solution. Maybe using a singleton is the correct solution, maybe it isn't. But understanding all your options and the strength/weakness of each one is going to be the best way to solve this issue. Unfortunately, you haven't provided enough context to your problem for me, or anyone for that matter, to give you a solid recommendation.
The best way to manage global objects is not having them at all. Based on my experience, in a lot of cases there are alternative options instead using singletons. There is so good explained in this post
shared preference is good but some time you will feel problem when do some modification make static constant variable in one pojo java class and use this variable anywhere.because shared preference will not change value after use or unless you dint modify .shared preference retrieving and storing is not very unfriendly. if you use constant you can modify easily .only one class you have to hit
Is there a way to make a collection of class files/objects and then have them used in an interactive main file? So let's say I want to make a program to store information interactively where different classes are designed to hold different information. Then I would have an interactive main file where I made instances of these classes which would collectively hold the information I want stored. And then any changes or anything I do in this interactive main file is then saved.
I understand that this might be a very odd inquiry and maybe some other program might be useful for this. If so, feel free to point me in the right direction.
Here are two solutions that are good for the purpose you mentioned in your comment.
The first one is called Serialization. This let's you save your java object to your hard drive, and retrieve it later.
The second, (and in this case, more preferable option in my opinion), is using a Database.
A database is a compliment to your program, that stores data. You can then use "Queries" to access this data, and update it. Almost every database software is compatible with java.
I would look into MySQL
The reason I think a database would be better for your purpose is that they are already highly optimized, and are designed to have multiple people accessing and writing to them at once. If you wanted just want one person to use this program at a time however, serialization might be easier to implement.
Absolutely! Your main class would use the standard input (perhaps Scanner input = new Scanner(System.in);) and output (System.out.println()). To interact with your other classes, most simply, just put them in the same folder (if you are interested take a look at Java packages). If you have a Dog class in the same folder as your main class, you can freely create Dog objects in your main class. I hope this helps!
As a side note, because you mentioned storing information with different classes, you might be interested in the Java Collections Framework.
I have written a math game in Java, and have distributed some copies to a few beta-testers. The problem is that the version I have given them is saving the GameData via object serialization, which I found out is mainly for sending Objects, or in this case, ArrayLists of GameData, over a network. It is NOT persistance; that is what a relational database is for. Knowing this, I would like to know if it would be better to create a database on the beta-tester's machine (and rewrite the game), or continue with the Object serialization version of the game, and then retrieve the Objects when they are ready to send the data?
My guess would be to just move their data to a database that is created on their computer, and then give them the database version of the game. That way, the data can be persisted and be much easier to manipulate. What turns me away from that idea is the question of how am I going to write their database into mine (in the future)?
Although relatively rare, there are still lots of applications that use serialization for storage and retrieval of objects. It's not wrong to do this, just slightly unusual. If it's working for you, stick with it because DB's are a heavyweight solution. What you found out, about serialization, is only an opinion and an ill-formed one at that.
In terms of using an embedded database, two options to consider are SQLite and HyperSQL. However, serialization is also an option, and in my opinion it should be your default option if you've already implemented it. Some considerations:
With serialization you've generally got to retrieve the entire object, which is slow if you've got an object with several dozen fields and you only want to read one of them. If you're making queries like these, then use a database. I suspect that you're just reading in all of your serialized objects at startup and serializing them back out to disk at shutdown, in which case there's no reason to use a database instead of serialization.
Java's default serialization mechanism is fairly slow. You may want to consider another serialization mechanism, such as Kryo or Jackson, but only if you're not happy with your program's serialization performance.
It is difficult to advise on the best choice of technology without knowing what you are persisting and why.
If the state is simply a snapshot of your game state (i.e. a save file) or a "best scores" table, then you don't need a database. Serializing using JSON, XML or ... Java Object serialization is sufficient.
If the state needs to be read or updated incrementally or shared with other applications ... or users on other machines ... then a database is more appropriate.
Serialization mechanisms are problematic if the requirements include incremental changes, etcetera. You end up building a database-like layer over the top of the serialization.
As to whether you should stick with Java serialization ... or switch to JSON or XML or something like that:
Object serialization is simple, but it can be fragile if you change the classes that you are serializing. This fragility can be mitigated, but it is messy and you lose the simplicity. (You need to write custom readObject and writeObject methods that know how to read "old versions" of the serialized objects.)
JSON and XML are a bit more complicated, but still relatively simple if you use an object binding mechanism.
It is worth noting that changes to the persisted object classes (or the database schemas) are potentially problematic no matter what you do. There is no easy universal solution to this problem.
UPDATE
Given the additional information that you provided in your first comment (below), it seems like you don't need a database in the game itself. All you need is something that can read and analyse the session state save files that your beta testers provide for you. Indeed, it doesn't even seem like the actual app needs to be able read the files. (But that's unclear, because you've not said what the real purpose of these files is ... or at least, not what the entire purpose is.)
It is also worth noting that you are probably saving the wrong information if your aim is to tune the sets of questions. What you really need to do is record the length of time and whether the user got the right or wrong answer and the time ... for each individual question. And you probably need to know what the actual answer given was ... so that you can spot cases where the user's answer was actually right and you "marked" it as wrong ... or vice versa.
"What turns me away from that idea is the question of how am I going to write their database into mine (in the future)?"
Exactly. If you hadn't prematurely "analysed" the data, you wouldn't have this problem.
But ignoring that, it seems like that a simple state saving mechanism is sufficient to meet your (still hypothetical / inferred) requirement of keeping a personal score board for the end user. Your "tuning" stuff would be better implemented using a custom log file. I cannot see any value in incorporating a database as part of the app itself.
I presume you are doing java serialisation, If so there is nothing wrong with it. Just be aware of its limitations - Different versions of java might not be able to retrieve the file.
Also If you change the Class, previous saved data can not be retrieved.
If you decide to change you could look at Xml, JSon, Protocol Buffers, Thrift, Avro etc as well as a DB.
Note:
Xml is builtin in to java
Java Db (Derby) is also in Java
Other serialisation schema's require a seperate library.
Basically what I need to know is this:
I have to show a drop down list of countries to my users each country also has a code associated to it. I will have to work with both the country and the code What would be the best approach:
-We (the dev.) are thinking about a table in our app database with this data, or XML file.
-Our "architect" says that is old school and that we should use constants in our app with a map that associates the country with the code
Please Help me feel smart
I agree with you that you should not hard code this or use constants. There are a few good options depending on yours needs:
Java Properties Files - If you just have a few key-value pairs to store, these are the simplest way and easy to use.
XML Storage - If you are looking for persistence and are looking at XML for storage, I would recommend looking at JAXB. It is part of Java 6 and will make your life easier than trying to use the DOM.
Database Persistence - If you have more data that is changing often, you could also look at storing it in a database. JPA is a great standard library for doing this. That is probably overkill for what you are looking for though.
Bottom line is hard coding is a thing of the past. There are lots of great ways to get data in quickly and easily without resorting to hard coding everything.
Countries rarely change, so adding them statically as code or a config file seems reasonable. If you don't use a database for anything else, don't add one just for this feature.
If you already have XML parsing in your app, use an XML file to define the data. It already solves all kinds of issues (for example if you need to add a second attribute per country or something).
If you don't use XML for anything else, I suggest to give it a try. It doesn't add much to your app. Otherwise, use a plain text file, maybe a CSV one.
The different methods have different advantages and drawbacks:
Database:
allows you to use the country data in queries
data can be changed without redeploying the app
editing the data requires you to write some sort of frontend or do it manually via some generic SQL browser
requires database access code, and some sort of caching strategy
Any country-based logic in the code can break when the DB changes, or has to be reflected in the DB
XML:
Very easy to edit
can be changed without recompiling the app, but changes have to be deployed somehow
Requires parsing code and some sort of caching strategy
Any country-based logic in the code can break when the XML changes, or has to be reflected in the XML
Code:
Easy to edit - for developers
Changes require compilation and deployment
Requires no extra technical layers
Code and country data can't get out of synch
All in all, the "code as data" solution is indeed the nicest, if the compile&deploy step for each change is acceptable to you. The other solutions create overhead and duplication of structure (or even logic) - and no, they don't magically make it "safe" to do last-minute changes "because it's not code". Code is data, and data is code.
In short your architect is wrong (Or at least he is if your paraphrase of his position is accurate). It shouldn't be in the code.
This data is not static; a country's name changes, a new one is founded, or some cease to exist.
As far as what mechanism, it doesn't necessarily matter. Just make sure you can retrieve the data easily, that you have unit tests, and that there is straightforward mechanism to update the data.
I think that "table solution" has more flexible approach:
1. You can manage data and connecting properties
2. You can work with table directly
3. You can create associated map, based on db table))
I would certainly not use them as constants in the code.
Names can change, while countries can be created, merge, disappear, etc.
If you are already using a database, adding this may make sense. For one, it ensures that the codes that may be stored with client data are valid in terms of your country code list. So if a country disappears but a client record still refers to it, the data stays valid.
Make sure that your UI loads and caches the list; no point making a query every time if you can avoid it.
By the way, correctly handling countries in an internationalized application is much more complicated than just dealing with renames. For example, if a country or part of a country declares independence, some countries will recognize it, while others do not.