In my Android application, I have a list of custom objects
ArrayList<Poke> pcList = new ArrayList<>();
Later in my code, I have save and load methods, that use Java OOS, and OIS to function. I have used these exact methods in other projects and know they work properly.
I believe I am having an issue with saving and loading a list of custom objects.
Here are the lines I'm calling to save, as well as load my list.
// save
oos.writeObject(pcList);
...
// load
pcList = (ArrayList<Poke>)ois.readObject();
Any ideas why I can't properly load/save with my list of custom objects?
Here is the interface that links a few similar objects:
public interface Poke {
int getNum();
String getName();
String getType();
int getValue();
boolean getShiny();
String getImageName();
}
Here is one of the similar object classes
public class BasicPoke implements Poke {
boolean shiny = false;
Random randomInt = new Random();
int iRandom = randomInt.nextInt(34 - 1) + 1;
int iShiny = randomInt.nextInt(31 - 1) + 1;
public int getNum(){
return this.iRandom;
}
public String getName(){
return this.pokeNames[iRandom-1];
}
public String getType(){
return this.pokeTypes[iRandom-1];
}
public int getValue(){
return 1;
}
public boolean getShiny() {
return (iShiny == 15);
}
public String getImageName() {
String threeDigitInteger = String.format(Locale.getDefault(),"%03d", this.getNum());
return (this.getShiny()) ? "icon"+threeDigitInteger+"s" : "icon"+threeDigitInteger;
}
String pokeNames = {"..","..",".."};
String pokeTypes = {"..","..",".."};
Please implement Serializable for the BasicPoke class. And by the way, could you tell us what issue (exception) when you load/save a list of objects?
Thanks,
Nghia
Related
As the title suggest, how do I do that? I have searched everywhere in the internet, maybe I didn't search for the right word or something. But please help me.
Object[] FlyingObject = new FlyingObject[3];
FlyingObject[0] = new Helicopter();
FlyingObject[1] = new Airplane();
FlyingObject[2] = new Drone();
Public static Object[] CopyFlyingObject(Object[] C){
Object FlyingObjectCopy = new Object(C.length);
// ...I got no idea how to continue from here
}
Using clone() is not allowed and you aren't allowed to find the name of the class either. I have copy constructor in my other classes but I have no idea how to call it when we're using object, especially with an object array with unknown classes throughout the array.
Edit:
My Subclass code
'''java
int speed;
double price;
Helicopter(){
speed = 0;
price = 0.0;
}
Helicopter(Helicopter c){
speed = c.speed;
price = c.price;
}
public Airplane extends Helicopter{
String brand;
Airplane(){
super();
brand = "";
}
Airplane(Airplane c){
super(C);
brand = c.brand;
}
public String getBrand(){
return brand;
}
}
public Drone{
//practically the same for here
}
'''
I am working on a program that is supposed to implement an electronic store. I had to create 3 classes (desktop, laptop and fridge) with specific defined functionality which I did. I am stuck on how to create the Electronic store class in which the constructor for this class
must create three instances of each of the previous three classes (9 items in total, using the
constructors defined in those classes) and store them within the ElectronicStore instance being created. I am unsure on how to do the above and would appreciate assistance. Below is what I have gotten so far.
// Desktop class
public class Desktop{
double speed = 0;
int ram, storage = 0;
boolean storageType;
public Desktop(double s, int r, int p, boolean t){
speed = s;
ram = r;
storage = p;
storageType = false;
}
// This is a String representation of the Desktop object
//#Override
public String toString(){
return "#"+speed+"#"+ram+"#"+storage;
}
}
// Laptop class
public class Laptop{
double CPU;
int RAM, storage, size;
boolean storeType;
public Laptop(double C, int R, int st, int si){
CPU = C;
RAM = R;
storage = st;
size = si;
storeType = false;
}
// This is a String representation of the Desktop object
public String toString(){
return "#"+CPU+"#"+RAM+"#"+storage+"#"+size;
}
}
// Fridge class
public class Fridge{
double fridge;
boolean freezer;
String color;
public String toString(){
return "#"+fridge+"#"+color;
}
}
// ElectronicStore class (which i am stuck with)
public class ElectronicStore{
public ElectronicStore()
{}
}
You create an instance of a class like so:
Desktop desktopOne = new Desktop(x, y, z);
To store them you can either have class variables (like you have for speed, ram) etc., or you could use a data structure like a list. Further clarification needed on that point.
I think it should be something like this
public class ElectronicStore{
private ArrayList<Fridge> fridges = new ArrayList<>();
public ElectronicStore()
{
Fridge fridge1 = new Fridge();
Fridge fridge2 = new Fridge();
Fridge frigde3 = new Fridge();
fridges.add(fridge1);
fridges.add(fridge2);
fridges.add(fridge3);
...
}
}
And you have to do the same thing to create the other objects.
Is it possible to make the following code cleaner with less repetition using annotations?
I know it would be possible with java 8 closures, but trying to get this working on java 6/7
Variable x = new Variable(this,"HClass","HC"){
#Override
String getValue(Player p){
return getHeroFromPlayer(p).getHeroClass().getName();
}
};
Variable y = new Variable(this,"HSecClass","HSC"){
#Override
String getValue(Player p){
return getHeroFromPlayer(p).getSecondClass().getName();
}
};
Variable z = new Variable(this,"HLevel","HL"){
#Override
String getValue(Player p){
return getHeroFromPlayer(p).getLevel();
}
};
Variable a = new Variable(this,"HMastered","HMa"){
#Override
String getValue(Player p){
return getHeroFromPlayer(p).isMaster(getHeroFromPlayer(p).getHeroClass()) && (heroSClass == null || getHeroFromPlayer(p).isMaster(heroSClass))
? LocaleType.MESSAGE_HEROES_TRUE.getVal() : LocaleType.MESSAGE_HEROES_FALSE.getVal();;
}
};
This goes on for some time, where they are all added to a map, which returns the results lazily.
Edit: I was hoping that annotations would allow me to do something along the lines of
#Variable("HLevel","HL")
String getHLevel(){getHeroFromPlayer(p).getlevel();}
Edit: Variable.java
abstract class Variable {
final private VariableGroup vg;
final private List<String> keys = new Vector<String>();
Variable(VariableGroup vg,String...varargs){
this.vg = vg;
for (String s:varargs){
keys.add(s);
}
}
abstract String getValue(Player p);
}
Based on your comments you can do something like this
#Variable("Primary Class")
public String getHClass(Player p) {
return getHeroFromPlayer(p).getHeroClass().getName();
}
#Variable("Primary Class Level")
public int getHLevel(Player p) {
return getHeroFromPlayer(p).getHLevel();
}
#Variable("Secondary Class")
public String getHSecClass(Player p) {
return getHeroFromPlayer(p).getSecondClass().getName();
}
#Variable("Secondary Class Level")
public int getHLevel(Player p) {
return getHeroFromPlayer(p).getHSecLevel();
}
Note: there is no need for all fields to return a String. To get this information you can do the following
Class heroClass =
for(Method method : heroClass.getMethods()) {
Variable var = method.getAnnotation(Variable.class);
if (var == null) continue; // ignore Object.getClass()
String description = var.value; // text to display to users
String attributeName = method.getName().substring(3); // cut "get"
String initials = attributeName.replaceAll("[a-z]+", "");
}
It's hard to say what can be improved without seeing the code for the Variable class. My first question is why are you are creating anonymous inner classes just to return a value for the getValue method? Why not just add a value parameter to the constructor and update the method to return that value?
I have a situation where I will be receiving 2+ ArrayList<Widget> and I need to be able to merge all the lists and remove any duplicate Widget so that I wind up with only 1 ArrayList<Widget> that contains all Widgets from all the merged lists, but without any duplicates.
Assume Widget has an overridden equals method that can be used for determining whether two Widgets are duplicates, although there may be a better way:
public ArrayList<Widget> mergeAndRemoveDupes(ArrayList<Widget> widgets...) {
// ???
}
Looking for the most algorithmically efficient way of accomplishing this. I am happy to use Apache Commons or any other open source libs that would help me out too! Thanks in advance!
For each ArrayList<Widget>, add each element to a Set<Widget> (HashSet or TreeSet, depending on whether they can be ordered in some way, or are hashable) utilizing addAll. Sets contain no duplicates by default.
You can convert this Set back into an (Array)List if you need to at the end.
Note you will need to implement hashCode for your Widget class if you decide to use a HashSet, but if you have an overridden equals, you should do this anyway.
Edit: Here's an example:
//Either the class itself needs to implement Comparable<T>, or a similar
//Comparable instance needs to be passed into a TreeSet
public class Widget implements Comparable<Widget>
{
private final String name;
private final int id;
Widget(String n, int i)
{
name = n;
id = i;
}
public String getName()
{
return name;
}
public int getId()
{
return id;
}
//Something like this already exists in your class
#Override
public boolean equals(Object o)
{
if(o != null && (o instanceof Widget)) {
return ((Widget)o).getName().equals(name) &&
((Widget)o).getId() == id;
}
return false;
}
//This is required for HashSet
//Note that if you override equals, you should override this
//as well. See: http://stackoverflow.com/questions/27581/overriding-equals-and-hashcode-in-java
#Override
public int hashCode()
{
return ((Integer)id).hashCode() + name.hashCode();
}
//This is required for TreeSet
#Override
public int compareTo(Widget w)
{
if(id < w.getId()) return -1;
else if(id > w.getId()) return 1;
return name.compareTo(w.getName());
}
#Override
public String toString()
{
return "Widget: " + name + ", id: " + id;
}
}
If you want to use a TreeSet but don't want to implement Comparable<T> on your Widget class, you can give the set itself a Comparator object:
private Set<Widget> treeSet;
....
treeSet = new TreeSet<Widget>(new Comparator<Widget>() {
public int compare(Widget w1, Widget w2)
{
if(w1.getId() < w2.getId()) return -1;
else if(w1.getId() > w2.getId()) return 1;
return w1.getName().compareTo(w2.getName());
}
});
I would do it this way
Set<Widget> set = new HashSet<>(list1);
set.addAll(list2);
List<Widget> mergeList = new ArrayList<>(set);
Use Set Collection Class,
ArrayList<Widget> mergeList = new ArrayList<widget>();
mergeList.addAll(widgets1);
mergeList.addAll(widgets2);
Set<Widget> set = new HashSet<Widget>(mergeList);
ArrayList<Widget> mergeListWithoutDuplicates = new ArrayList<widget>();
mergeListWithoutDuplicates .addAll(set);
return mergeListWithoutDuplicates;
Now here Set will remove all duplicates values from your ArrayList.
I have a load of images of musical symbols which I need to do some processing on and for each one I need to get the integer code corresponding to its file name. There are 23 possible file name strings and 23 integer code and there are many images with the same name under different directories.
The solution I have so far is given (abbreviated) below. I have just defined a load of int and String constants and then written a method which is just a huge chain of if statements to do the translation.
What would be a better way to achieve the same effect? The way I've done it seems really awful! I thought about using some kind of Map, but I wasn't sure of the best way to do so.
public class Symbol {
public static final int TREBLE_CLEF = 0;
public static final int BASS_CLEF = 1;
public static final int SEMIBREVE = 2;
// ...
public static final String S_TREBLE_CLEF = "treble-clef";
public static final String S_BASS_CLEF = "bass-clef";
public static final String S_SEMIBREVE = "semibreve";
// ...
public static int stringCodeToIntCode(String strCode) {
if (strCode == S_TREBLE_CLEF) {
return TREBLE_CLEF;
} else if (strCode == S_BASS_CLEF) {
return BASS_CLEF;
} else if (strCode == S_SEMIBREVE) {
return SEMIBREVE;
} //...
else {
return -1;
}
}
}
I think you are looking for Enum where you can have String constant and its value.
Example:
public enum YourEnumClass{
STRING_CONST (5),
STRING_CONST2 (7),
.....
//constructor
//getValue() method
}
read linked tutorial for more details.
enum StringToInt{
TREBLE_CLEF(0),
......
}
Enum is the way to go.
Another example:
public enum Color {
WHITE(21), BLACK(22), RED(23), YELLOW(24), BLUE(25);
private int code;
private Color(int c) {
code = c;
}
public int getCode() {
return code;
}
how about a hashmap
HashMap<String,Integer> hm=new HashMap<String,Integer();
hm.put("treble-clef",0);
//rest
and get it by using this
int value=hm.get("treble-clef");