Home > Back-end >  how to write complex if condition with File array in the lamba expression of stream API Android Java
how to write complex if condition with File array in the lamba expression of stream API Android Java

Time:10-17

I have the following code

private ArrayList<String> findPhotos(Date startTimestamp, Date endTimestamp, String keywords, String longitude, String latitude) {
     
     ArrayList<String> photos = new ArrayList<String>();
     File[] fList = file.listFiles();
        if (fList != null) {
            for (File f : fList) {
                if (((startTimestamp == null && endTimestamp == null) || (f.lastModified() >= startTimestamp.getTime()
                        && f.lastModified() <= endTimestamp.getTime())
                ) && (keywords == "" || f.getPath().contains(keywords))
                        && (longitude == "" || f.getPath().contains(longitude))
                        && (latitude == "" || f.getPath().contains(latitude)))
                    photos.add(f.getPath());
            }
        }
    return photos
}

This function take five parameters:

  1. Startime time
  2. endtime
  3. keywork
  4. longitude
  5. latitude

I filter them out to get the only desired results. I want to transfer this file array into lambda array and then perform following code.

Filter(startTimestamp == null && endTimestamp == null)

or

Filter(f -> f.lastModified() >= startTimestamp.getTime())

and

Filter(f -> f.getPath().contains(keywords) or (keywords == ""))

and

Filter(keywords == "" || f -> f.getPath().contains(keywords))

and

Filter(latitude== "" || f -> f.getPath().contains(latitude))
Filter(keywords == "" || f -> f.getPath().contains(keywords))

and then get only paths, then

.collect(Collectors.toList());

Once I filter them out the File array and then add only file paths into Arraylist<String>. Can anyone help me to turn this one into lambda expression?

CodePudding user response:

There are several issues with your given approach:

  • As others have already mentioned, the point of a lambda expression is that it should be short and easy to understand.
  • To get the logical and of your multiple logical expressions you should chain the filter(f -> ...) calls. This is better than putting all the logic into one giant lambda expression.
  • You need to understand the difference between == and equals. So instead of keywords == "" you probably want keywords.equals("").
  • You cannot use ArrayList<String> because .collect(Colllectors.toList()) is declared to give a List<String>.

Considering all this you might end up with something like this

private List<String> findPhotos(Date startTimestamp, Date endTimestamp, String keywords, String longitude, String latitude) {
{
    File[] fList = file.listFiles();
    if (fList == null)
        return new ArrayList<String>();
    List<String> photos = Arrays.stream(fList)
        .filter(f -> f.lastModified() >= startTimestamp.getTime())
        .filter(f -> f.getPath().contains(keywords))
        .filter(f -> keywords.equals("") || f.getPath().contains(keywords))
        .filter(f -> latitude.equals("") || f.getPath().contains(latitude))
        .filter(f -> keywords.equals("") || f.getPath().contains(keywords))
        .map(f -> f.getPath())  // convert File to String
        .collect(Collectors.toList());
    return photos;
}

CodePudding user response:

I believe the following should achieve your desired result.

private List<String> findPhotos(Date startTimestamp,
                                Date endTimestamp,
                                String keywords,
                                String longitude,
                                String latitude) {
    return java.util.Arrays.stream(new file.listFiles())
                           .filter(f -> startTimestamp == null || f.lastModified() >= startTimestamp.getTime())
                           .filter(f -> endTimestamp == null || f.lastModified() <= endTimestamp.getTime())
                           .map(file -> file.getPath())
                           .filter(path -> keywords.isEmpty() || path.contains(keywords))
                           .filter(path -> longitude.isEmpty() || path.contains(longitude))
                           .filter(path -> latitude.isEmpty() || path.contains(latitude))
                           .collect(Collectors.toList());
}
  • Method stream, in class java.util.Arrays, converts an array into a stream. In the above code, that stream will contain instances of class java.io.File.
  • Method map, in interface java.util.stream.Stream, returns a new stream that, in the above code, contains String elements.
  • Finally, all the paths that pass all the filters are collected into a java.util.List.
  • Related