What's Lazylist

What's LazyList?

Lazy List is lazy loading of images from sd-card or from server using urls. It is like on demand loading of images.

Images can be cached to a local sd-card or your phone's memory. URL is considered the key. If the key is present in the sd-card, images get displayed from sd-card, otherwise it downloads the image from the server and caches it to a location of your choice. You can set a cache limit. You can also choose your own location to cache images. Cache can also be cleared.

Instead of the user waiting to download large images and then displaying them, lazy list loads images on demand. Since images are cached, you can display images offline.

https://github.com/thest1/LazyList. Lazy List

In your getview

imageLoader.DisplayImage(imageurl, imageview);

ImageLoader Display method

    public void DisplayImage(String url, ImageView imageView) //url and imageview as parameters
{
imageViews.put(imageView, url);
Bitmap bitmap=memoryCache.get(url); //get image from cache using url as key
if(bitmap!=null) //if image exists
imageView.setImageBitmap(bitmap); //display iamge
else //downlaod image and dispaly. add to cache.
{
queuePhoto(url, imageView);
imageView.setImageResource(stub_id);
}
}

An alternative to Lazy List is Universal Image Loader

https://github.com/nostra13/Android-Universal-Image-Loader. It is based on Lazy List (it works on the same principle), but it has lot of other configurations. I would prefer to use Universal Image Loader because it gives you more configuration options. It can display an error image if a download failed. It can display images with rounded corners. It can cache on disc or memory. It can compress an image.

In your custom adapter constructor

  File cacheDir = StorageUtils.getOwnCacheDirectory(a, "your folder");

// Get singletone instance of ImageLoader
imageLoader = ImageLoader.getInstance();
// Create configuration for ImageLoader (all options are optional)
ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(a)
// You can pass your own memory cache implementation
.discCache(new UnlimitedDiscCache(cacheDir)) // You can pass your own disc cache implementation
.discCacheFileNameGenerator(new HashCodeFileNameGenerator())
.enableLogging()
.build();
// Initialize ImageLoader with created configuration. Do it once.
imageLoader.init(config);
options = new DisplayImageOptions.Builder()
.showStubImage(R.drawable.stub_id)//display stub image
.cacheInMemory()
.cacheOnDisc()
.displayer(new RoundedBitmapDisplayer(20))
.build();

In your getView()

  ImageView image=(ImageView)vi.findViewById(R.id.imageview); 
imageLoader.displayImage(imageurl, image,options);//provide imageurl, imageview and options

You can configure Universal Image Loader with other options to suit your needs.

Along with LazyList/Universal Image Loader you can view this website for smooth scrolling and performance.
http://developer.android.com/training/improving-layouts/smooth-scrolling.html.

What is the difference between List.view and LazyList?

Stream elements are realized lazily except for the 1st (head) element. That was seen as a deficiency.

A List view is re-evaluated lazily but, as far as I know, has to be completely realized first.

def bang :Int = {print("BANG! ");1}

LazyList.fill(4)(bang) //res0: LazyList[Int] = LazyList(<not computed>)
Stream.fill(3)(bang) //BANG! res1: Stream[Int] = Stream(1, <not computed>)
List.fill(2)(bang).view //BANG! BANG! res2: SeqView[Int] = SeqView(<not computed>)

What are the differences between LazyList and List in Scala?

LazyList is a new type introduced in Scala Standard Library 2.13.1.

  • The type it's an immutable one and it's placed into scala.collection.immutable package. The major difference between the common List type is the fact that the elements of the LazyList are computed lazily, so only those elements that are requested are computed. By this means, a lazy list can have an infinite number of elements.
  • In terms of performance, the two types (LazyList and List) are comparable.
  • A LazyList is constructed with an operator having a similar-looking to the one specific to the List type (::), #::.
  • Being lazy, a LazyList can't produce a StackOverFlowError in a recursive loop, as an old List could do.

What's the difference between LazyList and Stream in Scala?

NthPortal, a contributor to LazyList, states in Update and improve LazyList docs #7842

The key difference between LazyList and Stream - and its key feature -
is that whether or not it is lazy is evaluated lazily. I'm not sure
how best to convey that.

jwvh states in related question

Stream elements are realized lazily except for the 1st (head) element.
That was seen as a deficiency.

Scala 2.13 release notes state

immutable.LazyList replaces immutable.Stream. Stream had different laziness behavior and is now deprecated. (#7558, #7000)

View vs LazyList

I still feel that there could be advantages when using a single regex pattern.

val pattern = List("the name and age are (\\w+), (\\d+)"
,"name:(\\w+),age:(\\d+)"
// add more as needed
,"n=(\\w+),a=(\\d+)"
).mkString("|").r

def transform(subject: String): Option[String] =
pattern.findFirstMatchIn(subject)
.map(_.subgroups.filter(_ != null).mkString)

Imageloader class creates lazylist folder in gallery. How to avoid it

I got my solution by changing my FileCache class and its destination folder

public class FileCache {
private File cacheDir;
private File nomediaFile;
String NOMEDIA = " .nomedia";
public FileCache(Context context) {
// Find the dir to save cached images
if (android.os.Environment.getExternalStorageState().equals(
android.os.Environment.MEDIA_MOUNTED)) {
cacheDir = new File(Environment.getExternalStorageDirectory()
+ "/mydir");
if (cacheDir.mkdir()) {
nomediaFile = new File(
Environment.getExternalStorageDirectory() + "/mydir/"
+ NOMEDIA);
if (!nomediaFile.exists()) {
try {
nomediaFile.createNewFile();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
} else {
cacheDir = context.getCacheDir();
}
if (!cacheDir.exists())
cacheDir.mkdirs();
}

public File getFile(String url) {
// I identify images by hashcode. Not a perfect solution, good for the
// demo.
// String filename=String.valueOf(url.hashCode());
// Another possible solution (thanks to grantland)
@SuppressWarnings("deprecation")
String filename = URLEncoder.encode(url);
File f = new File(cacheDir, filename);
return f;

}

public void clear() {
File[] files = cacheDir.listFiles();
if (files == null)
return;
for (File f : files)
f.delete();
}
}

How to create LazyList Scala using LazyList.iterate?

It looks like you do not use LazyList syntax correctly. You need to use it as follow:

LazyList.iterate(List(BigInt(1)))(nextLine).take(4).force

First parameter of iterate is start element that will passed in the function - second parameter of iterate. The take need to do several iterations and force need to evaluate result.

Sequence vs LazyList

LazyList computes each element only once regardless of how many times the list is traversed. In this way, it's closer to a sequence returned from Seq.cache (rather than a typical sequence). But, other than caching, LazyList behaves exactly like a list: it uses a list structure under the hood and supports pattern matching. So you might say: use LazyList instead of seq when you need list semantics and caching (in addition to laziness).

Regarding both being infinite, seq's memory usage is constant while LazyList's is linear.

These docs may be worth a read.

Why are Scala's LazyList's elements displayed as unevaluated after being computed?

Instead of using LazyList.apply, any of the following work (without evaluating their arguments):

  • LazyList.tabulate(3)(fun)
  • fun(1) #:: fun(2) #:: fun(3) #:: LazyList.empty
  • LazyList.range(1, 4).map(fun)

  1. Why do we want LazyList's arguments like fun(1) to be computed right away? Why do we cast away the call-by-need strategy when initializing? Are there any other cases where such a thing happens? Note that no output is produced when we use map instead of writing this down manually, as expected.

I don't think it is desirable that fun(1) be computed right away, but it follows from the fact that you used LazyList.apply to construct your list. LazyList(fun(1), fun(2), fun(3)) is syntactic sugar for LazyList.apply(fun(1), fun(2), fun(3)) and the type signature for that function is def apply[A](elems: A*): LazyList[A]. Note that the arguments of that function are not call by name.

So: why is LazyList.apply not defined with call-by-name arguments?

  1. it is impossible in Scala to define a variadic function with by-name arguments
  2. def apply actually comes from SeqFactory which is mixed into most collection companion objects. The LazyList companion object might be the one place in the collections library where the companion object apply isn't a helpful addition.
  1. Why are no elements displayed as evaluated? If they are indeed unevaluated, what was this triple "PROCESSING..." thing about? If not, why does println claim so?

LazyList only knows when elements are evaluated because you forced them through accessing them in LazyList. In the case of using LazyList.apply, the following happens:

  1. the arguments are evaluated when LazyList.apply is initially called
  2. LazyList.apply calls LazyList.from, which is going to create a LazyList by lazily iterating through the intermediate Seq materialized in step 1

By the time step 2 has finished, the LazyList doesn't know that its contents are evaluated. Furthermore, the spine of the list is itself unevaluated.

:sprint in GHCi isn't a great comparison because it is much more omniscient in its understanding of when things are evaluated. It does this by crawling the runtime heap and printing _ when it runs across thunks. By comparison, println just calls out to LazyList#toString, which is a regular Scala method.



Related Topics



Leave a reply



Submit