javaandroidsharedpreferenceshashsetlinkedhashset

LinkedHashSet does not main insertion order?


I am currently building an Android app where I display quotes from famous people. I have a home screen and 2 other screens, where I am displaying all quotes and the other where I display favourite quotes.

So, when I hit the like button in the screen of AllQuotesActivity the quote and author will be saved in a LinkedHashSet, which will be saved in SharedPreferences, so my FavouriteQuotes Activity can obtain the data. I can obtain the data, but the data is mixed, even though other links say that LinkedHashSet maintains the insertion order. Maybe I did something wrong. Here are the important code snippets:

AllQuotesActivity.java:

SharedPreferences sharedPref;
Set<String> set = new LinkedHashSet();

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.all_quotes);

    Resources res = getResources();
    Context context = getApplicationContext();
    this.sharedPref = context.getSharedPreferences(
            "MyPref", Context.MODE_PRIVATE);
    final String[] quotesAndAuthors = res.getStringArray(R.array.quotes);

    button3.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            set.add(quotesAndAuthors[counter]);
            set.add(quotesAndAuthors[counter + 1]);
        }
    });

}

@Override
public void onPause() {
    super.onPause();
    Log.d("RichQuotes", "Its paused mkay");

    Editor editor = sharedPref.edit();

    editor.putStringSet("quotesAndAuthors", this.set);
    editor.commit();
}

}

FavouriteQuotesActivity.java:

SharedPreferences sharedPref;
Set<String> set = new LinkedHashSet();

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.favourite_quotes);

    Resources res = getResources();
    Context context = getApplicationContext();
    this.sharedPref = context.getSharedPreferences(
            "MyPref", Context.MODE_PRIVATE);

    set = sharedPref.getStringSet("quotesAndAuthors", null);

    for (Iterator<String> it = set.iterator(); it.hasNext(); ) {
        String s = it.next();
        Log.v("test", s);
    }

I removed unnecessary code.

In the FavouriteQuotesActivity.java I am logging the set to check its values. The log-outputs and the outputs on the screen are the same, both unsorted the same way.


Solution

  • Set set = new LinkedHashSet();

    In this line, you instantiate a new empty LinkedHashSet object. This object was then assigned to the variable named set.

    set = sharedPref.getStringSet("quotesAndAuthors", null);

    In this line, you reassigned the set variable to point to some other object, some Set object returned by your call to getStringSet. We do not know the concrete class of this second object that implements the Set interface. You can ask by calling getClass.

    Your first set, the empty LinkedHashSet, went unused. With no other references pointing to it, that set became a candidate for eventual garbage-collection.


    By the way, the more general super-interface for LinkedHashSet should be SequencedSet (Java 21+) rather than Set since you want to be aware of the fact that the set is sequenced.

    Change:

    Set set = … ;
    

    … to:

    SequencedSet sequencedSet = … ;