Understanding code specific functional concepts - java

I am relatively new to struts and java. I have been trying to understand the following piece of code.
List<LabelValueBean> dbList = getCardProductList();
ConcurrentMap<Integer, ProductItem> ret = new ConcurrentHashMap<Integer, ProductItem>();
for (LabelValueBean lb : dbList) {
ProductItem pi = new ProductItem();
pi.setId(Integer.valueOf(lb.getId()));
pi.setCode(lb.getCode());
pi.setName(lb.getDescription());
LabelValueBeanAuxCol[] aux = lb.getLabelvaluebeanauxcol();
pi.setTypeProduct(Boolean.TRUE);
if (null != aux) {
for (LabelValueBeanAuxCol element : aux) {
if (null != element
&& "PRDCT_SVC_IND".equals(element.getName())) {
pi.setTypeProduct(Boolean.valueOf("Y".equals(element
.getValue())));
}
}
}
pi.setNeedSetup(Boolean.TRUE);
ret.put(pi.getId(), pi);
}
return Himms2LookupUtil
.<ConcurrentMap<Integer, ProductItem>> setValueInCache(
Himms2Names.CARD_SERVICE_PRODUCT_LIST, ret);
}
With repect to the code block around "PRDCT_SVC_IND", how would a name of the column be mapped to the labelvaluebean?
Though I have an idea on the concurrent map and the key value pair functionality, I am pretty unsure about most of the concepts here and have tried searching on the internet without much luck. I would want a more clearer overview of what the above lines actually mean(in general ofcourse), in terms of the concepts used here like the concurrenthashmap, list(labelvaluebean) etc.
Any inputs would be greatly appreciated.

Code is doing following things :-
1) Getting CardProductList in first line and storing reference in a dbList object as
List<LabelValueBean> dbList = getCardProductList();`
2) Creating ConcurrentMap of key value .
3) Start iterating CardProductList and perform following operations on each CardProductList object -
a) Crates ProductItem object.
b) setting CardProduct object values (id, code, name) into ProductItem object.
d) setting ProductItem.typeProduct to TRUE.
c) getting Labelvaluebeanauxcol and store it in a LabelValueBeanAuxCol[] array instance called aux.
d) now check if aux is not null then iterates aux array and checks if(elemet is not null AND element name IS EQUAL TO "PRDCT_SVC_IND"
THEN
set ProductItem.TypeProduct to True if element.value = Y
ELSE
set ProductItem.TypeProduct to FALE
e) set ProductItem.NeddSetup = TRUE
f) set ProductItem.id and ProductItem into ConcurrentMap.
4) Store ConcurrentMap in cache

Related

How to make a sublist refers to his original ArrayList?

I have a homework to do in java about ArrayList and Generics types.
I have 2 classes :
-> CoupeDeA
-> TableauPartiel
CoupeDeA is just a describer from where to where an array is cut.
(It contains only two private integer variables "begin" and "end")
TableauPartiel is the class where the ArrayList is.
My problem is I need to create a method in TableauPartiel like this :
public TableauPartiel<E> coupe(CoupeDeA coupe)
And the TableauPartiel returned needs to be a reference of my intial TableauPartiel. Example :
Integer[] arr = {8,7,6,5};
TableauPartiel<E> tab = new TableauPartiel<>(arr);
TableauPartiel<E> tab2 = tab.coupe(1,3);
tab2.set(1,45);
This code is supposed to set 45 at index 1 of my tab2 and at the same time set 45 at index 2.
But I tried many different ways and I managed to get the sublist, but it is not pointing to my original ArrayList.
For example, I tried something like this :
private ArrayList<E> tableau;
...
public TableauPartiel<E> coupe(Coupe coupe)
throws IndexOutOfBoundsException {
if (coupe.getBegin() >= 0 && coupe.getEnd() <= tableau.size()) {
TableauPartiel<E> tab = new TableauPartiel<>((E[]) new Object[coupe.getEnd()-coupe.getBegin()]);
for (int i = 0; i < coupe.getEnd()-coupe.getBegin(); ++i) {
tab.set(i, this.get(coupe.getBegin()+i));
}
return tab;
} else {
throw new IndexOutOfBoundsException();
}
}
How can I do to get a sublist which refers to his original ArrayList?
I've found a solution for my code with the subList method and by switching the signature of my ArrayList to List but my teacher doesn't want us to use subList finally.
Here is my code with the subList method :
TableauPartiel<E> tab;
if (coupe.getDebut() >= 0 && coupe.getFin() <= taille()) {
if (coupe.getFin() == -1)
tab = new TableauPartiel<>(tableau.subList(coupe.getDebut(),taille()));
else
tab = new TableauPartiel<>(tableau.subList(coupe.getDebut(),coupe.getFin()));
return tab;
} else {
throw new IndexOutOfBoundsException();
}
}
Few small things first:
stick to English words in your code. Especially in names of classes, functions, variables, etc - names have to reveal intentions (without Google Translate). Best not to obtain a bad habit by letting yourself do otherwise.
I am not so sure how your Coupe is expected to work (is 0 a legal min number or 1?) but coupe.getEnd() <= tableau.size() might get out of hand
Now my suggestion for the solution:
I suggest you modify your TableauPartiel class to have start and end integer fields in addition to private ArrayList<E> tableau; reference you already have. Maybe add a new 'copy constructor' accepting an instance of
TableauPartiel (from which you can copy reference to tableau) and two int values indicating which part of the original tableau you can use (trick here is to also look at start and end values of the object you're 'sublisting' from). That way, when you're calling #coupe you can check for validity of the input numbers (as you already do) and simply return a new TableauPartiel object with a reference to this and method params - start and end values. Add some indexes manipulation logic using those start and end to whatever methods your TableauPartiel has and you should be good to go.

Get a string list of values from a generic object

So I have an Object that comes in that can be any of 100 different specific objects, with different elements inside it, from other objects, lists, sequences, primitives etc.
I want to strip the values in a depth first fashion to make a string of simple values with a delimiter between them. I have mapped the fields and stored them elsewhere using recursion/reflection that only happens once a new Object type comes in for the first time.
An example of how I'm storing the data in the database for a few simple example objects:
Object A layout table: Timestamp = 12345 Fields = Length|Width|Depth
Object B layout table: Timestamp = 12345 Fields = Height|Weight|Name
Object A layout table: Timestamp = 12350 Fields = Length|Width|Depth|Label
Object A sample: Timestamp = 12348 Values = 5|7|2
Object A sample: Timestamp = 12349 Values = 4|3|1
Object B sample: Timestamp = 12346 Values = 75|185|Steve Irwin
Object A sample: Timestamp = 12352 Values = 7|2|8|HelloWorld
Below is my current solution. I'm seeking improvements or alternatives to the design to accomplish the goal stated above.
Currently I get the object in and translate it to JSON using gson.toJson(); From that, I cycle through the JSON to get values using the code below. Issue is, this code is very CPU intensive on the low end CPU I am developing for due to the fact that there are many samples coming in per second. Overall purpose of the application is a data recorder that records real time samples into a SQLite database. I have also attempted to store the unmodified JSON into a SQLite BLOB column, but this is terribly inefficient with regards to DB size. Is there a better/more efficient method for getting values out of an object?
I don't have an issue storing the field mapping since it only needs to be done once, but the value stripping needs to be done for every sample. I know you can do it via reflection as well, but that is also processing heavy. Anyone have a better method?
public static List<String> stripValuesFromJson(JsonElement json)
{
// Static array list that will have the values added to it. This will
// be the return object
List<String> dataList = new ArrayList<String>();
// Iterate through the JSONElement and start parsing out values
for (Entry<String, JsonElement> entry : ((JsonObject) json).entrySet())
{
// Call the recursive processor that will parse out items based on their individual type: primitive, array, seq etc
dataList.addAll(dataParser(entry.getValue()));
}
return dataList;
}
/**
* The actual data processor that parses out individual values and deals with every possible type of data that can come in.
*
* #param json - The json object being recursed through
* #return - return the list of values
*/
public static List<String> dataParser(JsonElement json)
{
List<String> dataList = new ArrayList<String>();
// Deal with primitives
if (json instanceof JsonPrimitive)
{
// Deal with items that come up as true/false.
if (json.getAsString().equals("false"))
{
dataList.add("0");
} else if (json.getAsString().equals("true"))
{
dataList.add("1");
} else
{
dataList.add(json.getAsString());
}
// Send through recursion to get the primitives or objects out of this object
} else if (json instanceof JsonObject)
{
dataList.addAll(stripValuesFromJson(json));
} else if (json instanceof JsonArray)
{
// Send through recursion for each element in this array/sequence
for (JsonElement a : (JsonArray) json)
{
dataList.addAll(dataParser(a));
}
} else if (json instanceof JsonNull)
{
dataList.add(null);
} else
{
errorLog.error("Unknown JSON type: " + json.getClass());
}
return dataList;
}
One thing you could try out is writing your own JSON parser which simply emits values. I have more experience in JavaCC so I'd take one of existing JSON grammars and modify it so that it only outputs values. This should not be too complicated.
Take for example the booleanValue production from the mentioned grammar:
Boolean booleanValue(): {
Boolean b;
}{
(
(
<TRUE>
{ b = Boolean.TRUE; }
) | (
<FALSE>
{ b = Boolean.FALSE; }
)
)
{ return b; }
}
Basically you will need to replace returning the boolean value with appending "1" or "0" to the target list.
ANTLR is another option.

Fetch value from a set object in java

I'm iterating a set object to find a particular value. Is there any short way to fetch instead of iterating it? Here is my code
for(Tree t : assignedTrees) {
println t.treeName;
}
The above code will return the expected value.
assignedTrees is the set object
Set<Tree> assignedTrees = new HashSet<Tree>()
println assignedTrees will return
[Tree{id=null, treeName=Mango}]
Can I fetch the treeName instead of iterating?
You can fetch an object from a set by calling mySet.get(object). However, in your case you wish to fetch an object based on one of its attributes. The best way to do this is with a map - e.g.
Map<String, Tree> trees = new HashMap<>();
trees.put(treeObject.treeName, treeObject);
Tree myTree = trees.get("myTreeName");
Note that if you're putting your own objects into sets or maps, you must override the equals and hashcode methods, or very strange things will happen.
In general you can use lambda to find any/first element that fullfils any condition. For example:
Set<Integer> coolStrings = new HashSet<String>();
coolStrings.add("HEHE")
coolStrings.add("NOPE")
coolStrings.add("JP2GMD")
coolStrings.add("1234")
try{
String nice =
coolStrings.stream().filter(
(str) -> { return str.equals("JP2GMD") ||
str.equals("2137"); }
}).findFirst().get();
)
System.out.println("Yay, i found a REALLY cool string! : " + nice);
}
catch(NoSuchElementException e){
System.out.println("Not even one awesome string was found :(");
}
It will print "JP2GMD"
(I didn't compile it, there might be some minor syntax errors)
Working with Stream class is extremally handy (as for java standards)

Javolution FastSortedMap in Threaded Environment

I'm trying to find an alternative to using java.utils.TreeMap in a threaded environment due to the memory TreeMap consumes and doesn't free, using Sun JDK 1.6. We have a constant resizing TreeMap, which needs to keep sorted by key:
public class WKey implements Comparable<Object> {
private Long ms = null;
private Long id = null;
public WKey(Long ms, Long id) {
this.ms = ms;
this.id = id;
}
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((id == null) ? 0 : id.hashCode());
result = prime * result + ((ms == null) ? 0 : ms.hashCode());
return result;
}
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
WKey other = (WKey) obj;
if (id == null) {
if (other.id != null)
return false;
} else if (!id.equals(other.id))
return false;
if (ms == null) {
if (other.ms != null)
return false;
} else if (!ms.equals(other.ms))
return false;
return true;
}
#Override
public int compareTo(Object arg0) {
WKey k = (WKey) arg0;
if (this.ms < k.ms)
return -1;
else if (this.ms.equals(k.ms)) {
if (this.id < k.id)
return -1;
else if (this.id.equals(k.id)) {
return 0;
}
}
return 1;
}
}
Thread 1
-------------------------
Iterator<WKey> it = result.keySet().iterator();
if (it.hasNext()) {
WKey key = it.next();
/// Some processing here
result.remove(key);
}
Constantly retrieves the first element within the TreeMap and then
removes it.
Threads 2, 3, and 4
-------------------------
for (Object r : rs) {
Object[] row = (Object[]) r;
Long ms = ((Calendar) row[1]).getTimeInMillis();
Long id = (Long) row[0];
WKey key = new WKey(ms, id);
result.put(key, row);
}
Are bulk processing threads which process returned results from various
services, which are generally basic POJOs. POJOs are generated a key
based off their id and timestamp using the key above. I cannot
modify the POJO to implement a Comparator, so I must use this key.
After keys have been identified and process, they are inserted into a
shared tree map where they are getting pulled off in sorted order by
a processing thread.
We were using:
Map<WKey, Object[]> result =
Collections.synchronizedMap(new TreeMap<WKey, Object[]>());
We also tried using ConcurrentSkipListMap:
SortedMap<WKey, Object[]> result =
new ConcurrentSkipListMap<WKey, Object[]>();
We are experimenting with big data and need a collection which sufficiently utilizes memory any time remove or put is used in a threaded environment. We are inserting records by the hundred-thousands and removing elements from the top on a needed basis. We need a container which can scale. The problem with TreeMap is it never releases memory unless you recreate the container, new Collections.synchronizedMap(new TreeMap()) . This is an expensive operation to call in a threaded environment anytime a new entry is removed.
Alternatively, I've been experimenting with Javolution. It has a FastSortedMap, which seems to fit in nicely. However, I find their implementation and usage of the collection rather quirky and lacking sufficient documentation and examples.
They do have a few examples listed in the doc, which relate to the clases FastSortedMap is derived from, but nothing seems to work:
A high-performance hash map with real-time behavior. Related to FastCollection, fast map supports various views.
atomic() - Thread-safe view for which all reads are mutex-free and map updates (e.g. putAll) are atomic.
shared() - View allowing concurrent modifications.
parallel() - A view allowing parallel processing including updates.
sequential() - View disallowing parallel processing.
unmodifiable() - View which does not allow any modifications.
entrySet() - FastSet view over the map entries allowing entries to be added/removed.
keySet() - FastSet view over the map keys allowing keys to be added (map entry with null value).
values() - FastCollection view over the map values (add not supported).
I instantiated the following collection as a replacement to TreeMap:
private FastMap<WKey, Object[]> result =
new FastSortedMap<WKey, Object[]>().shared();
However, once another thread touches the container. All the member functions start to fail. I still encounter null values returned from result.iterator().next(), size() sometimes hangs, result.keySet().min() is very sluggish. result.get returns null. None of the examples in doc really show how the concurrent views are used, listed above. It's really frustrating.
I've looked a at Apache Collections, but I'm afraid I might experience the same issue as many of their sorting collections are derived from java.utils HashMaps and TreeMaps. I looked into Guava as well, but their sorted containers require you to implement comparable on both key and value. I was trying to avoid implementing comparable on the 'value'. I don't need to sort both objects. If I implemented comparable on the value, I would just use a sorted list, queue, or table. Highscale and Trove don't have ordered maps. Fastutils may be a candidate, but I'd have to synchronize everything manually, and I'm trying to save time.
I've reviewed others listed in the stackoverflow benchmark post, but the projects listed previously seem to be my best alternatives.
So far, I'm not convinced Javolution is everything they advertise on their site. My experience is that their implementation is very inconsistent, lacking documentation, and performs rather sluggish in threaded environments. TreeMap performs great; I just wish it wouldn't allocate in such large bursts and GC every now and then. However, I'm hoping there might be somebody out there to prove me wrong, may even demonstrate appropriate usage for Javolutions collections in a threaded environment.
Otherwise, if somebody knows a way around resizing Treemaps, without using 'new', or has solved similar/alternative instances working with threading and sorted maps, any info would be greatly appreciated!

ConcurrentHashMap putIfAbsent : atomicity when followed by a get() call

I wanted to discuss a specific use I have of a concurrent map to sense check my logic...
If I used ConcurrentHashMap, I can do the familar
private final ConcurrentHashMap<K, V> map = new ConcurrentHashMap<K, V>();
public V getExampleOne(K key) {
map.putIfAbsent(key, new Object());
return map.get(key);
}
but I realise that a race condition exists whereby if I remove the item from the map between the putIfAbsent and the get, the method above would return something that no longer exists in the collection. This may or may not be fine, but lets assume that for my use case, it's not ok.
What I'd really like is to have the whole thing atomic. So,
public V getExampleTwo(K key) {
return map.putIfAbsent(key, new Object());
}
but as this expands out to
if (!map.containsKey(key))
return map.put(key, value); [1]
return map.get(key);
which for line [1] will return null for first usage (ie, map.put will return the previous value, which for first time use is null).
I can't have it return null in this instance
Which leaves me with something like;
public V getExampleThree(K key) {
Object object = new Object();
V value = locks.putIfAbsent(key, object);
if (value == null)
return object;
return value;
}
So, finally, my question; how do the examples above differ in semantics?. Does getExampleThree ensure atomicity like getExampleTwo but avoid the null return correctly? Are there other problems with getExampleThree?
I was hoping for a bit of discussion around the choices. I realise I could use a non ConcurrentHashMap and synchronize around clients calling my get method and a method to remove from the map but that seems to defeat the purpose (non blocking nature) of the ConcurrentHashMap. Is that my only choice to keep the data accurate?
I guess that's a bit part of why you'd choose ConcurrentHashMap; that its visible/up-to-date/acurrate at the point you interact with it, but there may be an impact further down the line if old data is going to be a problem...
It sounds like you are trying to create a global lock object for a key.
Instead of deleting an entry with the possibility of have it re-created almost immediately, I would only delete the entry when you pretty sure its not needed ever again.
Otherwise, if you are using this for a lock, you can have two thread locking on different objects for the same key.
If its not ok, you can busy loop it.
public V getExampleOne(K key) {
for(Object o = null, ret = null; (ret = map.get(key)) == null; )
map.putIfAbsent(key, o == null ? o = new Object() : o);
return ret;
}
it can still be removed or replaced as soon as the loop exists so its effectively much the same as.
public V getExampleThree(K key) {
Object o = new Object();
map.putIfAbsent(key, o);
Object ret = map.get(key);
return ret == null ? o : ret;
}
So, finally, my question; how do the examples above differ in semantics?.
The difference is only the obvious.
Does getExampleThree ensure atomicity like getExampleTwo but avoid the null return correctly?
Yes.
Are there other problems with getExampleThree?
Only if you believe the very next call might not give you a different value (if you believe it can be removed in another thread)
The methods have different semantics:
getExampleOne is not atomic.
getExampleTwo returns null if the new object was inserted into the map. This differs from the behavior of getExampleOne, but it is atomic.
getExampleThree is probably what you want. It is atomic and it return the object that is in the map after the point in time of the putIfAbsent call. But it was problem when nulls are valid values in your application. The null return value is then ambiguous.
However, depending of the situation it might not be the actual object at the point in time when you use the return value. You then need explicit locking.
Why not simply use the first version and synchronize the method?
public synchronized V getExampleOne(K key) {
map.putIfAbsent(key, new Object());
return map.get(key);
}
While it won't provide you maximum parallelism, it's also true that you only have two operations and getExampleThree, while correct, is less readable and less easy to understand for someone else reading your code.
I think you will find the trick is to assume you will be non-atomic and handle it.
I am not really clear what you are looking for. Let me know if this is off at a tangent and I'll modify.
Perhaps you are looking for something like:
private final ConcurrentHashMap<String, Object> map = new ConcurrentHashMap();
/*
* Guaranteed to return the object replaced.
*
* Note that by the time this method returns another thread
* may have already replaced the object again.
*
* All we can guarantee here is that the return value WAS
* associated with the key in the map at the time the entry was
* replaced.
*
* A null return implies that either a null object was associated
* with the specified key or there was no entry in the map for
* the specified key wih 'null' as it's 'value'.
*/
public Object consistentReplace ( String key, Object newValue ) {
Object oldValue = map.get(key);
while ( !map.replace(key, oldValue, newValue) ) {
// Failed to replace because someone got in there before me.
oldValue = map.get(key);
}
return oldValue;
}

Categories

Resources