Performance comparison custom class versus arrays - android

Is it more performant to create a class
public class test {
private Circle c;
private String mac;
private Short abstand;
private Location ort;
public test (String mac, Circle c, Short abstand, Location ort){
this.c = c;
this.mac = mac;
this.abstand = abstand;
this.ort = ort;
}
public String erhalteMac()
{
return mac;
}
//etc.
}
Create an array list by using
ArrayList<test> karte = new ArrayList<test>();
and adding
test t = new test();
t.mac = "...";
karte.add(t);
etc.
to then see if there is an object that has a certain property
public static boolean hM(ArrayList<object> list, String mac) {
for (object object2 : list) {
if (object2.erhalteMac().equals(mac))
{
//work with object2 here.
return true;
}
}
return false;
}
versus simply creating four arrays for each type and iterating through only the mac array in my case and use the index of the matching mac string in each other array to make changes?

The Array method would be a tiny bit faster than the simple List, but
a HashMap would be a lot faster when there are more than a few object instances.

Related

Getting Nested JsonObjects & Arrays Using Retrofit Library

I got tired using this library, this is my first time using it and made a lot of success ways, but i'm a bit confused in getting the following Json :
{
"Guides":
{
"English": {"ArabicSony":"Test1","ArabicNexus":"Test2","ArabicSamsung":"Test3","ArabicHTC":"Test4"}
,"Arabic": {"EnglishSony":"Test1","EnglishNexus":"Test2","EnglishSamsung":"Test3","EnglishHTC":"Test4"}
}
}
Googled and saw a lot of guides and answered, and made my List like this :
public class PostItem {
List<PostItemArabic> Arabic;
List<PostItemEnglish> English;
}
class PostItemArabic{
private String ArabicSony;
private String ArabicNexus;
private String ArabicSamsung;
private String ArabicHTC;
public String getArabicSony() {
return ArabicSony;
}
public void setArabicSony(String arabicSony) {
ArabicSony = arabicSony;
}
public String getArabicNexus() {
return ArabicNexus;
}
public void setArabicNexus(String arabicNexus) {
ArabicNexus = arabicNexus;
}
public String getArabicSamsung() {
return ArabicSamsung;
}
public void setArabicSamsung(String arabicSamsung) {
ArabicSamsung = arabicSamsung;
}
public String getArabicHTC() {
return ArabicHTC;
}
public void setArabicHTC(String arabicHTC) {
ArabicHTC = arabicHTC;
}
}
class PostItemEnglish{
private String EnglishSony;
private String EnglishNexus;
private String EnglishSamsung;
private String EnglishHTC;
public String getEnglishSony() {
return EnglishSony;
}
public void setEnglishSony(String englishSony) {
EnglishSony = englishSony;
}
public String getEnglishNexus() {
return EnglishNexus;
}
public void setEnglishNexus(String englishNexus) {
EnglishNexus = englishNexus;
}
public String getEnglishSamsung() {
return EnglishSamsung;
}
public void setEnglishSamsung(String englishSamsung) {
EnglishSamsung = englishSamsung;
}
public String getEnglishHTC() {
return EnglishHTC;
}
public void setEnglishHTC(String englishHTC) {
EnglishHTC = englishHTC;
}
}
My Model :
private class Model {
private List<PostItem> Guides;
public List<PostItem> getGuides() {
return Guides;
}
public void setGuides(List<PostItem> roms_center) {
this.Guides = roms_center;
}
}
And printing the result like this :
List<PostItem> Guides = response.body().getGuides();
for(int i = 0 ; i < Guides.size() ; i ++ ) {
for (int b = 0; b < Guides.get(i).English.size() ; b++){
Log.LogInfo("English Result Is: " + Guides.get(i).English.get(i).getEnglishHTC());
Log.LogInfo("English Result Is: " + Guides.get(i).English.get(i).getEnglishNexus());
Log.LogInfo("English Result Is: " + Guides.get(i).English.get(i).getEnglishSamsung());
Log.LogInfo("English Result Is: " + Guides.get(i).English.get(i).getEnglishSony());
}
for (int b = 0; b < Guides.get(i).Arabic.size() ; b++){
Log.LogInfo("Arabic Result Is: " + Guides.get(i).Arabic.get(i).getArabicHTC());
Log.LogInfo("Arabic Result Is: " + Guides.get(i).Arabic.get(i).getArabicNexus());
Log.LogInfo("Arabic Result Is: " + Guides.get(i).Arabic.get(i).getArabicSamsung());
Log.LogInfo("Arabic Result Is: " + Guides.get(i).Arabic.get(i).getArabicSony());
}
}
My work isn't correct, and getting a lot of errors,
Here's the last error i got :
`Expected BEGIN_ARRAY but was BEGIN_OBJECT at line 3 column 18 path $.Guides
What's the way to make it correct ? `
Based on your models when you try to get the guides list your telling retrofit to populate an array. Retrofit is then getting the data and finding that it is a single object and not array. So you need to update your model to reflect the data returned. For example:
class PostItem {
List<Language> mLanguages;
}
class Language{
String mLanguageTitle; //for example english
List<String> mData; //for this is your list of data
}
Then in your activity instead of getting guides you would get just a post item for example:
response.body().getPostItem();
Hope it helps !
First of all, you can use the retrofit Gson library.
You can handle this in two ways:
Option 1: reformat your languages in your json to be an array like Doug says.
{
"Guides":
[
{"Lang":"English","ArabicSony":"Test1","ArabicNexus":"Test2","ArabicSamsung":"Test3","ArabicHTC":"Test4"}
, {"Lang":"Arabic","EnglishSony":"Test1","EnglishNexus":"Test2","EnglishSamsung":"Test3","EnglishHTC":"Test4"}
]
}
Then you will need to redesign your class to reflect this structure.
Like Doug sayd:
class PostItem {
List<Language> mLanguages;
}
Option 2: Create a custom json desirializer in your class. this will take the Json and break it down into whatever structure you want it to be.
public class PostItem implements JsonDeserializer
#Override
public MyDesirializer deserialize(JsonElement json, Type type,
JsonDeserializationContext context) throws JsonParseException {
JsonObject jarabic = (JsonObject) json.get("Arabic");
//whatever manipulations you want to do (fill with your own code)
PostItem item = new PostItem();
item.arabic = jarabic;
...
...
return item;
}

Weird ListView sort

I've got following problem:
As you can see on the picture, the CITROEN group header is not above the all Citroen car models, like e.g DACIA.
The weird thing is that there is around 20 Car Brands like BMW,AUDI...and every group header is above its children items, but not the CITROEN.
This listview is populated from the html file, which has the following structure:
<optgroup label="BMW">
<option value="225" >BMW X3 3.0si</option>
<option value="226" >BMW X5 3.0d A/T</option>
<option value="227" >BMW X5 4.8i A/T</option>
</optgroup>
<optgroup label="CITROËN">
<option value="67" >CITROËN C1 1.0i</option>
<option value="68" >CITROËN C1 1.4 HDi</option>
<option value="69" >CITROËN C2 1.1i</option>
I'm using custom adapter. Here is the source code of the comparing method:
#Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
progressDialog.dismiss();
adapter = new ModelsAdaper(CarsList.this, generateData());
/*Should sort the ListView alphabetically*/
adapter.sort(new Comparator<Model>() {
#Override
public int compare(Model lhs, Model rhs) {
return lhs.getTitle().compareTo(rhs.getTitle());
}
});
setListAdapter(adapter);
The generateData() method:
private ArrayList<Model> generateData() {
models = new ArrayList<Model>();
/*This loop adds car brands to the listview*/
for(String s: brands){
models.add(new Model(R.drawable.alfa_romeo_icon_52,s));
}
/*This loop inserts car models into the listview*/
int key;
for(int i = 0; i < hashMap.size(); i++) {
key = hashMap.keyAt(i);
models.add(new Model(hashMap.get(key)));
}
return models;
}
And finally, the Model class
public class Model {
private String title;
private boolean isGroupHeader = false;
private int icon;
/**
* This constructor will be used for creating instance od target_item
* #param title is content of the item
*/
public Model(String title){
this.title = title;
}
/**
* This constructor will be used for group headers
* #param icon is icon of the group
* #param title is name of the group
*/
public Model(int icon, String title){
this.icon = icon;
this.title = title;
isGroupHeader = true;
}
EDIT
As requested, here is the HTMLParser class source code. Its constructor is called from CarsList Activity, which extends ListActivity
public class HTMLParser {
private String value;
private InputStream is = null;
private Context context=null;
private org.jsoup.nodes.Document document = null;
SparseArray<String> hashMap = new SparseArray<String>();
private ArrayList<String> modelsList = new ArrayList<String>();
private ArrayList<String> brandsList = new ArrayList<String>();
/**
* Constructor is used to pass instance of CarsList Context to get html asset
* #param context instance of the CarsList activity context
*/
public HTMLParser(Context context) throws IOException {
this.context = context;
is = context.getAssets().open("modely aut.html");
document = Jsoup.parse(is,"UTF-8","http://example.com");
}
/**
* The purpose of this method is to parse car brands from html asset
* #return ArrayList of car brands
*/
public ArrayList<String> parseCarBrands(){
Elements models = document.select("optgroup");
for (Element e: models){
brandsList.add(e.attr("label"));
}
return brandsList;
}
/**
* Method parses all car models from html asset. For IO safety operations, it is recommended to call this method
* after parseCarBrands() method, because parseCarModels() method closes inputStream.
* #return SparseArray consisting of key: carID and value: car model
*/
public SparseArray<String> parseCarModels(){
try {
Elements models = document.select("option");
for (Element e: models){
int res = new Scanner(e.toString()).useDelimiter("\\D+").nextInt();
value = e.html();
modelsList.add(value);
hashMap.put(res,value);
}
} finally {
if(is!=null){
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return hashMap;
}
}
EDIT 2 Possible source of the problem
I have made some tests with the same code, but only in simple java project. It looks like some encoding issue.
when using
Elements models2 = doc.select("option");
for (Element e: models2){
int key = Integer.parseInt(e.attr("value"));
String modelName = e.html();
modelsList.add(value);
}
the output from System.out.println(modelName) looks like this:
CITROËN C4 1.6i 16V EP turbo
but when parsing just a brand names using String s = e.attr("label"); the output is as it should be.
Do you have any idea, where the problem can be? I will post other parts of the code, if it will be necessary.
I would like to thank you for all your time and effort you give to my question
I've made it, but it's such a stupid thing. I've changed few things in the parseCarModels()
First of all, I've changed the return type to LinkedHashMap<Integer,String>. Parsing the html now seems to be faster.
Then I've changed the value variable from String to CharSequence. This allowed me to use Html.fromHtml(e.html), so the final code looks like this:
public LinkedHashMap<Integer,String> parseCarModels(){
Elements models = document.select("option");
int key;
CharSequence value;
for(Element e: models){
key = Integer.parseInt(e.attr("value"));
value = Html.fromHtml(e.html());
hashMap.put(key,value.toString());
}
if(is!=null){
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return hashMap;
}
Thank you for all your help. I really appreciate that. I hope that this code isn't very ineffective

How to check arraylist contains this particular word in android?

I have ArrayList<String> in that I added 3-4 website names. Like, http://www.google.com, https://www.stackoverflow.com, etc. Now in my application if I type simply "google" then I want to compare that "google" word with the ArrayList<String>.
I am stuck here. Can anyone tell me how can I compare the string with the array object?
Thanks in advance.
To do so, you need to override implementation of contains(). I am giving you a simple example.
Custom ArrayList class
public class MyArrayList extends ArrayList<String> {
private static final long serialVersionUID = 2178228925760279677L;
#Override
public boolean contains(Object o) {
return indexOf(o) >= 0;
}
#Override
public int indexOf(Object o) {
int size = this.size();
if (o == null) {
for (int i = 0; i < size ; i++) {
if (this.get(i) == null) {
return i;
}
}
} else {
for (int i = 0; i < size ; i++) {
if (this.get(i).contains(String.valueOf(o))) {
return i;
}
}
}
return -1;
}
}
How to use
MyArrayList arrayList = new MyArrayList();
arrayList.add("http://www.google.com");
arrayList.add("https://www.stackoverflow.com");
arrayList.add("http://pankajchunchun.wordpress.com");
if (arrayList.contains("google")) {
System.out.println("ArrayList Contains google word");
}
if (arrayList.contains("igoogle")) {
System.out.println("ArrayList Contains igoogle word");
} else {
System.out.println("ArrayList does not Contains igoogle word");
}
Below is output for above code example
ArrayList Contains google word
ArrayList does not Contains igoogle word
See ArrayList Source Code for more custom implementation.
ArrayList.contains() test the the String through equals. From the documentation:
public boolean contains(Object o) Returns true if this list contains
the specified element. More formally, returns true if and only if this
list contains at least one element e such that (o==null ? e==null :
o.equals(e)).
example:
boolean contains = yourArrayListInstance.contains(yourString);
Edit. If you want to check for substring you have to loop on the ArrayList's content and call String.contains
You can iterate through your ArrayList<String> like
public String getWebsiteName(String toMatchString)
{
ArrayList<String> yourArrayList = new ArrayList<String>();
for (String webSiteName : yourArrayList)
{
if (webSiteName.contains(toMatchString))
return webSiteName;
}
return null;
}
and get the matching String
Use a helper function like this
public static boolean containsSubString(ArrayList<String> stringArray, String substring){
for (String string : stringArray){
if (string.contains(substring)) return true;
}
return false;
}

How to save Object (includes Array) in Preferences?

How to save Object in Preferences which looks like this:
public class ToDoList {
public String name;
public String date;
public ArrayList<Product> products = new ArrayList<Product>();
public boolean isChecked;
}
and then loads its values?
You could do it with serialization. Serialization of an object is a short unique String format of an object that can be serialized. Particularly almost every object can be serialized in java except from the View object. You won't have any problem in your case.
How to do it:
You should make class ToDoList implement Serializable and all classes that are used inside your object, ex Product. String, boolean ArrayList are serializable so you don't have to do anything.
When implementing serialization in an object you have to supply a serial version UID which would be then used to serialize.
So ToDoList would be something like:
public class ToDoList implelements Serializable {
private static final long serialVersionUID = //generate random by eclipse
.....
public ArrayList<Product> products = new ArrayList<Product>();
}
and Product:
public class Product implelements Serializable {
private static final long serialVersionUID = //generate random by eclipse
.....
}
then include this static helper class:
public class ObjectSerializeDeserialize {
public static String ObjectSerialization(Object obj)
{
ByteArrayOutputStream byteArray = new ByteArrayOutputStream();
try
{
ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteArray);
objectOutputStream.writeObject(obj);
objectOutputStream.close();
}
catch (Exception e) {
e.printStackTrace();
return "";
}
return new String(Base64.encode(byteArray.toByteArray(), 0));
}
public static Object ObjectDeserialization(String str)
{
byte[] byteArray = Base64.decode(str,0);
Object o;
try
{
ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(byteArray));
o = ois.readObject();
ois.close();
}
catch(Exception e)
{
e.printStackTrace();
return null;
}
return o;
}
}
and simply use the following code:
String todolistSer = ObjectSerializeDeserialize.ObjectSerialization(todolistObj);
the above line of code will return an empty String if something goes wrong and will print the detailed message in the log cat.
Then simply save the todolistSer as a String in preferences and reclaim your object like this:
ToDoList todolistObj = (ToDoList) ObjectSerializeDeserialize.ObjectDeserialization(todolistString);
suppress any warnings that are issued by the above method and you are done!
P.S. you can use the above solution whenever you have complicated structures that can not be saved as raw variables and you still don't want to use a database
Preferences are simple key ,value pairs. In your case better use SQLite.

Android save array of custom objects

I have a question about saving an arraylist of custom objects. I have a class called notitie:
public class Notitie implements Serializable{
private String titel = "";
private String type = "";
private String datum = "";
public void setTitel (String titel){
this.titel = titel;
}
public String getTitel(){
return titel;
}
public void setType (String type){
this.type = type;
}
public String getType(){
return type;
}
public void setDatum (String datum){
this.datum = datum;
}
public String getDatum(){
return datum;
}
}
I create some objects of Notitie and add them to my arraylist called notities
ArrayList<Notitie> notities = new ArrayList<Notitie>();
Notitie notitie1 = new Notitie();
notitie1.setTitel("Meting");
notitie1.setType("Watermeting");
notitie1.setDatum("22-09-12");
notities.add(notitie1);
Notitie notitie2 = new Notitie();
notitie1.setTitel("Meting2");
notitie1.setType("Watermeting2");
notitie1.setDatum("23-09-12");
notities.add(notitie2);
Notitie notitie3 = new Notitie();
notitie1.setTitel("Meting3");
notitie1.setType("Watermeting3");
notitie1.setDatum("24-09-12");
notities.add(notitie3);
Now I want to save the filled Arraylist on the device's storage so it can be accessed anytime. I used to save data as a String or some Integers with sharedpreferences but I can't save this Arraylist with that.
Does anybody have a solution?
Thanks in advance!
You do have a few options:
Use serialization, XML or JSON, and store your data in a File. Refer to this solution if you wanna implement serialization.
Store you data using SQLite. Have a look at this tutorial to get started.
EDIT : You might want to read this as well!

Categories

Resources