Collections.sort between Directories and Files - android

I am using Arraylist of strings:
ArrayList entries = new ArrayList(Arrays.asList(""));
and giving values dynamically. It may contain the names of Directories or Files.
I need to show entries in ListView such that, first all directories are shown in sort order then files in sort order.
Is this possible? if yes, any hint? Appreciate the help.. I am using
Collections.sort(entries);
to sort my entries.

Use the 2 parameter version with a custom comparator. Compare it such that:
boolean firstFileIsDirectory = file1.isDirectory();
boolean secondFileIsDirectory = file2.isDirectory();
if(firstFileIsDirectory && !secondFileIsDirectory){
return -1;
}
if(!firstFileIsDirectory && secondFileIsDirectory){
return 1;
}
return String.compare(filename1, filename2);

I have done it. Logic used: separate the entries into two ArrayList. One having directories other files. Sort these two ArrayLists separately. Finally add these two to "entries". Here is the code:
private void sortEntries(String path){
ArrayList<String> entriesDir = new ArrayList<String>(Arrays.asList(""));
ArrayList<String> entriesFile = new ArrayList<String>(Arrays.asList(""));
entriesDir.removeAll(entriesDir);
entriesFile.removeAll(entriesFile);
int fileCounter=0, dirCounter=0;
path = path.equals("/") ? "" : path;
for(int i=1;i<=entries.size();i++){
if((new File(path+"/"+entries.get(i-1))).isFile()) entriesFile.add(fileCounter++, entries.get(i-1));
else entriesDir.add(dirCounter++, entries.get(i-1));
}
Collections.sort(entriesDir,String.CASE_INSENSITIVE_ORDER);
Collections.sort(entriesFile,String.CASE_INSENSITIVE_ORDER);
entries.removeAll(entries);
entries.addAll(entriesDir);
entries.addAll(entriesFile);
}

Related

Android ArrayList<String> stored not restored back to its saved sorted order

I have an myArrayList which is to be stored and restored back in its saved sorted order. But the code does not do that. Why?
ArrayList<String> myArrayList
// save:
SharedPreferences prefs = PreferenceManager
.getDefaultSharedPreferences(getBaseContext());
SharedPreferences.Editor edit;
edit = prefs.edit();
edit.putStringSet("mydata", new LinkedHashSet<String>(myArrayList));
edit.commit();
// read:
myArrayList = new ArrayList<String>(PreferenceManager
.getDefaultSharedPreferences(getBaseContext()).getStringSet(
"mydata", new LinkedHashSet<String>()));
adapterAppList = new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1, android.R.id.text1,
myArrayList);
Is there any better way I can store the value of myArrayList and restored back to its original saved sorted order?
HashSet is not keeping orders, it is ordering for quickest find to it. You can convert list to json and save as string.
When you need to it, you can convert it to ArrayList from json with keeped ordering.
Example:
String listAsString = new Gson().toJson(arrayList); //list to string
List<String> arrayList = Arrays.asList(new Gson().fromJson(listAsString,String[].class)) //string to list
dont forget add library to build.gradle:
dependencies {
implementation 'com.google.code.gson:gson:2.8.6'
}
You can serialize arrayList like string:
1 with gson
public ArrayList<String> convertToArrayList(String json) {
if (TextUtils.isEmpty(json)){
return null; // or new ArrayList<>()
}
Type type = new TypeToken<ArrayList<String>>(){}.getType();
return new Gson().fromJson(json, type);
}
public String convertFromArrayList(ArrayList<String> list) {
if (list == null){
return null;
}
return new Gson().toJson(list);
}
2 without gson
public ArrayList<String> convertToArrayList(String st) {
if (!TextUtils.isEmpty(st)){
String[] str = st.split(",");
if (str.length > 0){
return new ArrayList<>(Arrays.asList(str));
}
}
return null;
}
public String convertFromArrayList(ArrayList<String> list) {
if (list!=null && !list.isEmpty()){
return TextUtils.join(",", list);
}
return null;
}
Yes, you are right, the order is not stored in string set, coz it is a set (duh).
When I was bugged with this, I got the serializing solution where, you can serialize your string.
Read this only if you haven't read about serializing, else go down and read my hack
In order to store array items in order, we can serialize the array into a single string (by making a new class ObjectSerializer (copy the code from – www.androiddevcourse.com/objectserializer.html , replace everything except the package name))
Entering data in Shared preference :
the rest of the code on line 38 -
Put the next arg as this, so that if data is not retrieved it will return empty array(we cant put empty string coz the container/variable is an array not string)
Coming to my Hack :-
Merge contents of array into a single string by having some symbol in between each item and then split it using that symbol when retrieving it.
If you are worried about splitting just look up "splitting a string in java".
[Note: This works fine if the contents of your array is of primitive kind like string, int, float, etc. It will work for complex arrays which have its own structure, suppose a phone book, but the merging and splitting would become a bit complex. ]
PS: I am new to android, so don't know if it is a good hack, so lemme know if you find better hacks.

How to cast List to String[] in Android

In my application I want use ChipView, from this Library : https://github.com/adroitandroid/ChipCloud
In this library for set lists , I should use string[].
In my application I get lists of Tag with this code :
response.body().getData().getTags()
And Tags model is :
#SerializedName("tags")
#Expose
private List<NewsDetailTag> tags = null;
...
public List<NewsDetailTag> getTags() {
return tags;
}
In above library I should add list with this codes :
chipCloud.addChips(someStringArray);
How can I convert List to string[] in android?
Please help me guys.
There is no need for a "conversion" at all! No need to waste memory :)
Take a look at the code of the library and see, what ChipCloud.addChips() does:
public void addChips(String[] labels) {
for (String label : labels) {
addChip(label);
}
}
Its just going through the elements of the array and adding each string individually with the addChip() method.
In your code, you can do this the same way with a list:
List<NewsDetailTag> tags;
String tagString;
ChipCloud chipCloud;
// Get the tags, initialize the chipCloud, etc ...
for (NewsDetailTag tag : tags) {
tagString = tag.getTheStringFromNewsDetailTag();
chipCloud.addChip(tagString);
}
You could even write your own class that extends ChipCloud and add a method that accepts a List parameter.
The only thing thats left to do is to get a String from your NewsDetailTags. But it looks like they are serializable anyways.
try this:
String[] newList = yourList.toArray(new String[]);
hope this works
List<NewsLineTag> tags = response.body().getData().getTags();
List<String> tagStrings = new ArrayList<String>();
//add some stuff
for (NewsLineTag tag : tags) {
tagStrings.add(tag.getSomeTextValueINeed());
}
chipCloud.addChips(tagStrings.toArray(new String[0]));
getSomeTextValueINeed() should be replaced with some method which will provide you with the String you want to show.
Duplicate of Converting 'ArrayList<String> to 'String[]' in Java
Java's List has a pretty convenient toArray() method you can use to convert a List to an Array of the same type.
However, since you have a List<NewsDetailTag> you will have to build the new array yourself.
It will look something like this:
String[] strings = new String[](list.size())
for(int i = 0; i < list.size(); i++) {
array[i] = list.get(i).getStringField();
}
Where getStringField() is whatever property on NewsDetailTag contains the String you want.

Check if ArrayList of Strings contains 50 different Strings one by one

How to check if ArrayList of strings contains every of 50 different strings from string array one by one and for every identical string in ArrayList to do something?
You can use this function to check if all Strings in your array are also in the ArrayList. If you want to add additional logic, like doSomething() each time a match is found, you should be able to adapt the code easily.
ArrayList myList; // let's assume its initialized and filled with Strings
String[] strArray; // let's assume its initialized and filled with Strings
//this function returns true if all Strings in the array are also in your arraylist
public boolean containsAll(myList, strArray){
//iterate your String array
for(int i = 0; i < strArray.length; i++){
if(!myList.contains(strArray[i])){
//String is not in arraylist, no need to check the rest of the Strings
return false;
}
}
return true;
}
Why not use LINQ?
List<String> duplicates = YourList.GroupBy(x => x)
.Where(g => g.Count() > 1)
.Select(g => g.Key)
.ToList();
Note that this will return all duplicates in a new List<string> , so if you want only want to know which items are duplicated in the source list, you could apply Distinct to the resulting sequence or use the solution given above

Saving multiple data one at a time in database in Android

I want to save multiple files to my database one by one.
And what happen here using my codes is this:
What I want to happen is like this one:
here is my code:
//Arraylist for getting the multiple brand code
ArrayList<String> content = new ArrayList<String>();
for (int j=0; j<checkSelected.length; j++) {
if(checkSelected[j]==true) {
String values = BrandListAdapter.mListItems.get(j);
//content.add(values);
Cursor rSubBrand = databaseHandler.getReport_SubBrandCode(values);
String SubBrandCode = rSubBrand.getString(rSubBrand.getColumnIndex(Constants.SUBBRAND_CODE));
content.add(SubBrandCode);
//Casting and conversion for SubBrand Code
String subBrand = content.toString();
//SAVE SUBBRAND
databaseHandler.SaveSubBrand(new Cons_iReport (ReportCode, subBrand));
Toast.makeText(getApplicationContext(), subBrand, Toast.LENGTH_LONG).show();
}
}
Mistakes:
content.add(SubBrandCode);
do you know how to remove the '[ ]' in the saved data? (e.g. [AC001]) All I want to save is the AC001 only.
Solutions:
Call clear() method of ArrayList before adding new values into it.
Its giving you [AC001] as you are subBrand by doing content.toString();. Don't convert it to string, instead use content.getString(position) and it will give you String value.

How to check if an Array contains specific term - Android

I currently have a statement which reads
if(Arrays.asList(results).contains("Word"));
and I want to add at least several more terms to the .contains parameter however I am under the impression that it is bad programming practice to have a large number of terms on one line..
My question is, is there a more suitable way to store all the values I want to have in the .contains parameters?
Thanks
You can use intersection of two lists:
String[] terms = {"Word", "Foo", "Bar"};
List<String> resultList = Arrays.asList(results);
resultList.retainAll(Arrays.asList(terms))
if(resultList.size() > 0)
{
/// Do something
}
To improve performance though, it's better to use the intersection of two HashSets:
String[] terms = {"Word", "Foo", "Bar"};
Set<String> termSet = new HashSet<String>(Arrays.asList(terms));
Set<String> resultsSet = new HashSet<String>(Arrays.asList(results));
resultsSet.retainAll(termSet);
if(resultsSet.size() > 0)
{
/// Do something
}
As a side note, the above code checks whether ANY of the terms appear in results. To check that ALL the terms appear in results, you simply make sure the intersection is the same size as your term list:
resultsSet.retainAll(termSet);
if(resultSet.size() == termSet.size())
You can utilize Android's java.util.Collections
class to help you with this. In particular, disjoint will be useful:
Returns whether the specified collections have no elements in common.
Here's a code sample that should get you started.
In your Activity or wherever you are checking to see if your results contain a word that you are looking for:
String[] results = {"dog", "cat"};
String[] wordsWeAreLookingFor = {"foo", "dog"};
boolean foundWordInResults = this.checkIfArrayContainsAnyStringsInAnotherArray(results, wordsWeAreLookingFor);
Log.d("MyActivity", "foundWordInResults:" + foundWordInResults);
Also in your the same class, or perhaps a utility class:
private boolean checkIfArrayContainsAnyStringsInAnotherArray(String[] results, String[] wordsWeAreLookingFor) {
List<String> resultsList = Arrays.asList(results);
List<String> wordsWeAreLookingForList = Arrays.asList(wordsWeAreLookingFor);
return !Collections.disjoint(resultsList, wordsWeAreLookingForList);
}
Note that this particular code sample will have contain true in foundWordInResults since "dog" is in both results and wordsWeAreLookingFor.
Why don't you just store your results in a HashSet? With a HashSet, you can benefit from hashing of the keys, and it will make your assertion much faster.
Arrays.asList(results).contains("Word") creates a temporary List object each time just to do linear search, it is not efficient use of memory and it's slow.
There's HashSet.containsAll(Collection collection) method you can use to do what you want, but again, it's not efficient use of memory if you want to create a temporary List of the parameters just to do an assertion.
I suggest the following:
HashSet hashSet = ....
public assertSomething(String[] params) {
for(String s : params) {
if(hashSet.contains(s)) {
// do something
break;
}
}
}

Categories

Resources