Firebase not sorting files alphabetically in android studio,? - java

I am using firebase storage for saving images, when I retrieve them on application, files are not sorting alphabetically.
Firebase sorting files by date time, first upload showing on first then second.
I have a lot of files and cannot upload these files one by one.
Is there any way to sort files by alphabetically.
like
001.png
002.png
003.png
004.png
005.png
…
`
private void saveAllSigns() {
showDialog();
for (int i = 0; i < SignNameList.length; i++) {
StorageReference storageReference = FirebaseStorage.getInstance().getReference().child(SignNameList[i]);
int finalI1 = i;
storageReference.listAll().addOnSuccessListener(new OnSuccessListener<ListResult>() {
#Override
public void onSuccess(ListResult listResult) {
List<StorageReference> list = listResult.getItems();
for (StorageReference str : list) {
long SIZE = 1024 * 1024;
str.getBytes(SIZE).addOnSuccessListener(new OnSuccessListener<byte[]>() {
#Override
public void onSuccess(byte[] bytes) {
saveData(bytes, str.getName(), finalI1);
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Log.d("SlashLog", "Firebase Exception: " + e.getMessage());
}
`
looking for solution

According to the Firebase documentation given by frank, listAll() call should be returning the files in lexicographical order.
Seems order of the files in the list is being changed by the for loop that iterates through the list. Maybe you should try sorting the list before iterating through it.
listAll() method is being called inside a for loop that iterates over the SignNameList. If the elements in the SignNameList array are in chronological order, then the listAll() method will return the files in chronological order as well.
As also mentioned here, Consistency of the result is not guaranteed if objects are inserted or removed while this operation is executing.

thanks for answer
but error has resolved from here in data base helper ORDER BY ASC
Cursor cursor = db.rawQuery("SELECT * FROM " + TABLE_SIGNS +" ORDER BY fileName ASC", null);

Related

Java PriorityQueue with Custom Objects not Sorting Correctly [duplicate]

This question already has answers here:
Why does PriorityQueue.toString return the wrong element order? [duplicate]
(4 answers)
Closed 8 months ago.
I don't completely understand how to use a Java PriorityQueue (max Heap) for custom objects.
I'm working on a LeetCode problem where my code must reorder the words in a sentence by word length. My instinct was that I could use a PriorityQueue to do the work of word-ordering for me. To do that, I thought I could track words with a custom object:
public class word implements Comparable<word>{
public String theWord;
public int len, order;
public word(String w, int order) {
this.theWord = w;
this.order = order;
this.len = w.length();
}
#Override
public int compareTo(word o) {
return this.len - o.len; // sorting behavior controlled here, right???
}
public String toString() {
return this.theWord+"("+this.order+") "; // for troubleshooting
}
}
Then:
public String arrangeWords(String sentence) {
PriorityQueue<word> maxHeap = new PriorityQueue<>(Comparator.naturalOrder());
String[] words = sentence.split(" ");
for( int i=0; i<words.length; i++ ) {
maxHeap.offer( new word(words[i], i) );
}
}
The first sentence I'm using to test is "leetcode is cool". (From the LC post.)
The ordering I'm hoping for is: "is cool leetcode" (shortest-to-longest word order)
But when I run the above code and check the PriorityQueue in the debugger, I see:
is(1) leetcode(0) cool(2)
Sooo... what the heck? I don't understand how this is ordered at all. This is not the original order (indicated by parenthesis), not in length order, not even in alphabetical order. I have no idea how the PriorityQueue is deciding how to order the word objects. I thought that the class word's compareTo() method would force the ordering that I want. (I've seen this with other SO posts.) But not so. Does someone see what I'm going wrong? Thank you.
You inserted them in priority queue. But then you need to poll the queue to get the right order of words.
while (!maxHeap.isEmpty()) {
System.out.println(maxHeap.poll());
}
Also please note the order field won't get altered just because you inserted them in priority queue. It just shows the order in which the word appears in original sentence.
Write that loop after your for loop where you inserted. Then execute again. You will see right order.
PriorityQueue( minHeap) maintains that the top element is of the lowest length . The remaining elements will be in random order. Once you poll the top element, then re-ordering happens( upHeapify -technically ) that makes the smallest from the remaining to become the top element. As already pointed out, you need to poll all the objects and make them part of your sentence.
Also, another way to go about the problem was -> you could have simply used the comparator on the array of String.
class Solution {
public static String arrangeWords(String text) {
String str[] = text.split(" ");
Arrays.sort(str, (a, b) -> a.length() - b.length());
String res = "";
for ( int i = 0; i< str.length; i++)
{
if ( i ==0 )
{
res += str[i].substring(0,1).toUpperCase() + str[i].substring(1) + " ";
}
else{
res += str[i].substring(0,1).toLowerCase() + str[i].substring(1) + " ";
}
}
return res.trim();
}
}

Removing an element form linked list in java, unexpected behavior

I am trying to implement lru cache in java using hashmap and linkedlist:
public static class LRUCache{
LinkedList<Integer> ll;
HashMap<Integer, Integer> map;
//HashSet<Integer> map;
int size;
LRUCache(int n){
ll = new LinkedList<>();
map = new HashMap<>();
size=n;
}
int refer(int page){
if(map.containsKey(page)){
Integer it = map.get(page);
//System.out.println("m.get(page)= " + map.get(page));
//System.out.println(it + " it+page " + page);
ll.remove(it);
} else{
if(map.size() >= size){
map.remove(ll.getLast());
ll.removeLast();
}
}
ll.addFirst(page);
//System.out.println(page + " page+peek " + ll.peekFirst());
map.put(page, ll.peekFirst());
return page;
}
}
In the refer function above, for the if condition where page is found in the map the value is getting successfully removed from the linked list, which I think should not work as I am keeping only the page value in the map.
Now interestingly when I put ll.remove(page); in the above code it breaks although the value of both page and it are same.
int refer(int page){
if(map.containsKey(page)){
Integer it = map.get(page);
//System.out.println("m.get(page)= " + map.get(page));
//System.out.println(it + " it+page " + page);
ll.remove(page);
} else{
if(map.size() >= size){
map.remove(ll.getLast());
ll.removeLast();
}
}
ll.addFirst(page);
//System.out.println(page + " page+peek " + ll.peekFirst());
map.put(page, ll.peekFirst());`enter code here`
return page;
}
I am really surprised by this behavior.
For the below test case, the first price of code works but the second doesn't, the only difference is ll.remove(it) and ll.remove(page) ,the values of it and page are same.
void printCache(){
System.out.print("| ");
for(int i=0;i<ll.size();i++){
System.out.print(ll.get(i) + " |" + " ");
}
System.out.println();
}
}
public static void main(String[] args) {
LRUCache lruCache = new LRUCache(4);
lruCache.refer(11);
lruCache.refer(12);
lruCache.refer(13);
lruCache.printCache();
lruCache.refer(11);
lruCache.printCache();
lruCache.refer(14);
lruCache.printCache();
lruCache.refer(13);
lruCache.printCache();
lruCache.refer(15);
lruCache.printCache();
}
Without diving into too much details of your code, there is very big difference between which method is being called when invoking ll.remove(page) and when involing ll.remove(it).
When calling ll.remove(it), the type of it is Integer, so the method called is LinkedList.remove(Object). From the documentation of this method:
Removes the first occurrence of the specified element from this list,
if it is present....
While when you call ll.remove(page), the type of page is int, so you actually call: LinkedList.remove(int). From the documentation of this method:
Removes the element at the specified position in this list....
One method is removing the index at page, while the other is removing the value matching it.
I think what you might wanted to do in the call to ll.remove(page) to achieve similar behavior is ll.remove(new Integer(page))
Here is a simple code that demonstrates this issue:
public static void foo(int x) {
System.out.println("Called foo(int)");
}
public static void foo(Integer x) {
System.out.println("Called foo(Integer)");
}
public static void main (String[] args) throws java.lang.Exception
{
int page = 5;
Integer it = new Integer(10);
foo(page);
foo(it);
foo(new Integer(page));
}
To keep two collection is expensive for cache why don't you use single collection. Linkedhashmap keeps the insertion order. Also you have to keep concurrency in mind. Maybe two hit at the same time will cost you data loss. Just wrap the map with Collections.synchronizedMap. Linkedhashmap can keep long type of key. You can put with time in millisecond as key. Then you can find the last used element by key search or just simply removing last inserted element.

UI keeps Updating in Debug but without it nothing happens

I want to populate a table with data.
The following Code are two bits out of the controller, because I sadly don't know which part is important.
Each function is supposed to take an Observable List which was declared in the main phase and clear it out.
Then add new Entries according to the current status of the arrays and in the end use populate() to populate the table with it.
But this sometimes fails. The data is added into the arrays, but it isn't shown in the table.
Has anybody an idea what could be the reason for that?
public void showAll() {
//Clear existing data
Main.data = FXCollections.observableArrayList();
//add new data on base of the arrays
for (int i = 0; i < Main.array_anz.length; i++) {
if (Main.array_pla[i] != 0) {
Main.data.add(new Article(Main.array_bez[i], Main.array_pla[i], Main.array_gew[i], Main.array_pre[i], Main.array_anz[i], Main.array_kat[i]));
} else {
i++;
}
}
//Show the data in the table
populate();
}
private void populate() {
ArtikelbezeichnungTable.setCellValueFactory(new
PropertyValueFactory<Article, String>("artikelbezeichnung"));
LagernummerTable.setCellValueFactory(new PropertyValueFactory<Article,
Integer>("lagernummer"));
GewichtTable.setCellValueFactory(new PropertyValueFactory<Article,
Double>("gewicht"));
AnzahlTable.setCellValueFactory(new PropertyValueFactory<Article,
Integer>("anzahl"));
KategorieTable.setCellValueFactory(new PropertyValueFactory<Article,
String>("kategorie"));
StorageTable.setItems(Main.data);
}

Add and remove item of recyclerview depending on distance

I am developing an application where a list of message (MESSAGE_RECIEVED) should be visible only in a certain distance (50, 100, 200, 300 or 400 meters)
For that I have an ArrayList of messages (MESSAGE_RECIEVED), a RecyclerView with a custom adapter and a fragment containing the RecyclerView and give it my ArrayList.
The methods I have now are the following:
To remove an entry (in my adapter):
public void removeAt(int pos) {
mMessagesList.remove(pos);
notifyItemRemoved(pos);
notifyItemRangeChanged(pos, mMessagesList.size());
}
To add an entry (in my adapter):
public void addAt(int pos, Message m){
mMessagesList.add(pos, m);
notifyItemInserted(pos);
}
Finaly my code that determine if an item is too far away:
ArrayList<String[]> operation = new ArrayList<>();
for (int i = 0; i < MESSAGES_RECEIVED.size(); i++){
if(dist <= distMax){
if(!MESSAGES_RECEIVED.get(i).isDisplayed()){
operation.add(new String[]{"add", String.valueOf(i)});
MESSAGES_RECEIVED.get(i).setDisplayed(true);
}
} else {
operation.add(new String[]{"remove", String.valueOf(i)});
}
}
for (String[] values : operation){
Log.i(TAG, "recalculateDistance: " + values[0] + " " + values[1]);
if(values[0].equals("add")){
int pos = Integer.valueOf(values[1]);
mRecyclerViewAdapter.addAt(pos, MESSAGES_RECEIVED.get(pos));
} else if(values[0].equals("remove")){
int pos = Integer.valueOf(values[1]);
mRecyclerViewAdapter.removeAt(pos);
}
}
This code do not work as items are removed from my ArrayList of message. I cannot delete them as they are used elsewhere (and I have IndexOutOfBoundsException because the position is out of the scope of the ArrayList).
On top of that I cannot delete them because if they are in the defined range people will not be able to see them.
Is there a way to hide items without deleting them? I though of duplicating my list of messages, don't know if this might work.
Thanks in advance guys!
Ok, I finally found somthing to make it works. I created another ArrayList and placed it in a static class (so that I can update the display from multiple place in the app)
Here is the methos I created
public static void updateDisplayedMessages(){
MESSAGES_DISPLAYED.clear();
getDistance(MESSAGES_RECEIVED);
for(Message m : MESSAGES_RECEIVED){
float dist = m.getDistance();
int distMax = Integer.valueOf(VALUE_PREF_RADIUS_GEO_FENCING);
if(dist < distMax){
MESSAGES_DISPLAYED.add(m);
}
}
}
Once this is called I call notifyDataSetChanged from my fragment and that's it! Probably not the most efficient way of implementing it but it works

Java date comparator issue

I'm having issues sorting out my comparator by dates. The date format should be in "dd/MM/yyyy" So I call in my information from an SQL Database and then convert strings to date by doing this:
public void setDeadlineDate(String deadDate) throws ParseException {
this.d_date = deadDate;
//convert strings to dates
formatter = new SimpleDateFormat("dd/MM/yyyy");
convertedDeadlineDate = (Date)formatter.parse(deadDate);
}
I then make a get method below to call for my comparator. I have to examples but there is always a discrepancy in regards to an odd date being out of place and the comparing not being right.
Example 1:
#Override
public int compare(JobRequest j1, JobRequest j2) {
if (j1.getConvertedDeadlineDate().before(j2.getConvertedDeadlineDate())) {
return -1;
} else if (j1.getConvertedDeadlineDate().after(j2.getConvertedDeadlineDate())) {
return 1;
}
else {
return 0;
}
}
Example 2:
public int compare(JobRequest j1, JobRequest j2){
return j1.getConvertedDeadlineDate().compareTo(j2.getConvertedDeadlineDate());
}
both these examples give me issues and my priorityqueue deadlinedate not to be in the correct order as I would like.
in my db they are saved as a varchar in the following format "01/12/2012" , 1st december 2012 as it wouldnt let me use their date function to have it in the english format.
is their a better way for me to convert strings and then compare or am i missing something?
thanks
EDIT:
output getting for ordered dates:
05/04/2011
16/12/2012
18/06/2012
17/12/2013
17/12/2013
16/12/2013
17/12/2013
14/08/2012
19/12/2013
Where I declare PriortyQueue:
private Comparator<JobRequest> comparator = new JobQueueComparator(); //calls my comparator
private PriorityQueue< JobRequest> scheduledJobs = new PriorityQueue<JobRequest>(100, comparator);
public void addJob(JobRequest job) {
// now add job to priority queue
scheduledJobs.add(job); // add jobs from the resultset into queue
}
scheduledJobs.add(job) just populates the queue from a resultset and keeps adding to queue until all fields in database have been read, see below
public void populateQueueFromDB() {
// create priority queue
try {
String url = "jdbc:mysql://localhost:3306/project";
Connection conn = DriverManager.getConnection(url, "root", "nbuser");
PreparedStatement stmt = conn.prepareStatement("SELECT user_id,s_date,e_date,d_date,department,projectname,projectapplication,priority,cores,disk_space,analysis FROM booking");
ResultSet rs;
rs = stmt.executeQuery();
//List<JobRequest> jobList = new ArrayList<JobRequest>();
while (rs.next()) {
JobRequest job = new JobRequest();
User user = new User();
user.setUserID(rs.getString("user_id"));
job.setUserID(user.getUserID()); // changes the /user id to the job.setuser id so can call for my queue print.
job.setStartDate(rs.getString("s_date"));
job.setEndDate(rs.getString("e_date"));
job.setDeadlineDate(rs.getString("d_date"));
job.setDepartment(rs.getString("department"));
job.setProjectName(rs.getString("projectname"));
job.setProjectApplication(rs.getString("projectapplication"));
job.setPriority(rs.getInt("priority"));
job.setCores(rs.getInt("cores"));
job.setDiskSpace(rs.getInt("disk_space"));
job.setAnalysis(rs.getString("analysis"));
schedulerPriorityQueue.addJob( job );
}
schedulerPriorityQueue.printQueue();
conn.close();
} catch (Exception e) {
System.err.println("Got an exception! ");
System.err.println(e.getMessage());
}
}
}
PRINT QUEUE:
public void printQueue() {
for (JobRequest jr : scheduledJobs) {
System.out.print(jr.getUserID() + "-->");
System.out.print(jr.getStartDate() + "--START-->");
System.out.print(jr.getEndDate() + "---END-->");
System.out.print(jr.getDeadDate() + "--DROP-->");
System.out.print(jr.getDepartment() + "-->");
System.out.print(jr.getProjectName() + "-->");
System.out.print(jr.getProjectApplication() + "-->");
System.out.print(jr.getPriority() + "--PRIORITY-->");
System.out.print(jr.getCores() + "-->");
System.out.print(jr.getDiskSpace() + "-->");
System.out.println(jr.getAnaylsis());
}
}
when you do: for (JobRequest jr : scheduledJobs) { ... you're actually using an implicit Iterator, which doesn't guarantee that the items will be returned in order of Priority (defined by your comparator).
Like mentioned above, the documentation states that:
This class and its iterator implement all of the optional methods of
the Collection and Iterator interfaces. The Iterator provided in
method iterator() is not guaranteed to traverse the elements of the
priority queue in any particular order. If you need ordered traversal,
consider using Arrays.sort(pq.toArray()).
Meaning that the order of the jobs in queue and the order of the iterator isn't necessarily the same.
If you just need to list the jobs, use the Arrays.sort approach mentioned in the docs.
If you want to make sure that your PriorityQueue is working, you'll have to use it as one, doing something like:
while(!scheduledJobs.isEmpty()) {
... = scheduledJobs.poll();
//print, do whatever
}
Keep in mind that this removes the elements from the Queue, and should only be used for testing purposes, or to actually handle the jobs as you need. But this should show you the dates in the actual Priority order.
It seems to me that there's some confusion on how the PriorityQueue should be used. I would say that the regular use case would be something like:
Add elements to the queue
Define a method to handle the "jobs" (each element), in the queue
While the queue isn't empty, get each element using poll (returns the smallest), and do whatever you need to do with it.
The documentation of PriorityQueue says that
The Iterator provided in method iterator() is not guaranteed to
traverse the elements of the priority queue in any particular order.
If you need ordered traversal, consider using
Arrays.sort(pq.toArray())
.
http://docs.oracle.com/javase/6/docs/api/java/util/PriorityQueue.html
This works perfectly for me:
public class JobRequest implements Comparable<JobRequest> {
static final DateFormat formatter = new SimpleDateFormat("dd/MM/yyyy");
Date convertedDeadlineDate;
Date getConvertedDeadlineDate() {
return convertedDeadlineDate;
}
public JobRequest(String deadDate) {
try {
convertedDeadlineDate = (Date) formatter.parse(deadDate);
} catch (ParseException e) {
e.printStackTrace();
}
}
#Override
public int compareTo(JobRequest j) {
return this.getConvertedDeadlineDate().compareTo(
j.getConvertedDeadlineDate());
}
public static void main(String[] args) {
List<JobRequest> list = new ArrayList<>();
list.add(new JobRequest("10/10/2010"));
list.add(new JobRequest("09/09/2009"));
list.add(new JobRequest("11/11/2011"));
list.add(new JobRequest("08/08/2008"));
Collections.sort(list);
for (JobRequest j : list) {
System.out.println(formatter.format(j.getConvertedDeadlineDate()));
}
}
}
Which results in the output:
08/08/2008
09/09/2009
10/10/2010
11/11/2011

Categories