Is there any java fly implementation?

I was looking for a flyweight template implementation and gave up after reaching page 20 of a Google search. Although there are many silly examples, it seems like no one has ever published a reimplementation in Java.

For me, flies really make sense if you need to store a lot of such instances, so it should be implemented as a collection. I would like Factory to implement the mapter / short / int / long mapper implementation and return either List, Set, or Map, which looks like a regular Object collection, but stores it as the inside of an array of primitives, thereby saving a lot of ram. Mapper will take an object of type X and map it to the primitive, or do it the other way around.

Is there something like this somewhere?

[EDIT] I am looking for a Collection library that supports this template, not just any example, of which hundreds.

+6
source share
6 answers

If you want to replace List, you can use TByteArrayList instead. If youw ant replace List, where MyClass {int a; T-object } you can use TIntObjectHashMap instead.

If you want to replace something with two fields that must be ordered, or three or more fields, you need to implement your own class that transfers arrays for storing data. This uses a column-based table model.

eg.

class MyClass { byte b; int i; String s; } class MyClassList { int size = 0; int capacity; byte[] bytes; int[] ints; String[] strings; MyClassList(int capacity) { this.capacity = capacity; } public void add(MyClass myClass) { if (size == capacity) resize(); bytes[size] = myClass.b; ints[size] = myClass.i; strings[size] = myClass.s; size++; } public void get(MyClass myClass, int index) { if (index > size) throw new IndexOutOfBoundsException(); myClass.b = bytes[index]; myClass.i = ints[index]; myClass.s = strings[index]; } } 

From Java 5.0, caches for automatic boxing are examples of flyweights.

 Integer i1 = 1; Integer i2 = 1; System.out.println(i1 == i2); // true, they are the same object. Integer i3 = -200; Integer i4 = -200; System.out.println(i3 == i4); // false, they are not the same object. 

If you want to read the code, look at Integer.valueOf (int) in your IDE or http://www.docjar.com/html/api/java/lang/Integer.java.html line 638

EDIT: Autoboxing for Integer uses IntegerCache, which is a collection. ArrayList is a class that wraps an array and has size ...

 private static class IntegerCache { static final int high; static final Integer cache[]; 
+3
source

I think Integer.valueOf (String s) is pretty flies. Since, as far as I know, it stores a certain number of created integers inside, so when you pass the string you passed earlier, it returns an existing instance to you.

+2
source

Have you seen a gang of four - design patterns? I will rewrite their implementation (albeit in C ++), if you want, but a little later.

This is one of those books you should have - you never know when it might come in handy.

+1
source

For your requirement, I think you should try Trove or Colt . These libraries support primitive collections.

+1
source

GNU Trove does something similar with the gnu.trove.decorator package (Map and Set only, not List).

Such a thing is rather ineffective, although, I doubt that there are many situations where a compromise is worth it.

Why not just use the appropriate primitive collections?

+1
source

I made a test program to see how well Flyweight would work in Java. For the record, I will describe my results here. Ymmv

1) If you have several fields in your objects, you will save some processor by combining them into one int or long. This is a pain in regards to programs and errors, but it is several percent faster, because access to several arrays is more expensive than bit manipulation. Moreover, the number of fields is increasing.

2) For small instances (4 status bytes), it will run about 25% slower, and then it will store the instance directly. But, ONLY if you do not create a new instance for each receipt. This is the real problem. The need to create a new instance at each receipt is very expensive; in this case, it is not 25% slower, but 500% slower!

3) I see two ways to save instance creation in get:

A) Your get method populates an existing instance instead of creating a new one. In other words, you pass the result object as input to the get method.

B) You use immutable instances, cache them, and return the cached instance from get. This is only useful if your list index is significant and you expect to reuse the same values ​​in your list. If you do this, you can also keep a direct link to your cached instance in your collection, and not to some state, because then you still pay only 4 bytes per instance for reference. In this case, your state must be 2 bytes or less before it makes sense to store the state instead of a link.

So, as the final answer, the reason why there is no universal library for Flyweight there is that it pays only under certain conditions, otherwise it really is not worth it.

0
source

Source: https://habr.com/ru/post/893667/


All Articles