I have generated model code from Ecore.
Within my model I have a derived reference: derivedThings.
What I want to do in the derivedThingsImpl is the following:
I want to traverse the whole model and depending on the element, I want to add it to a collection or not.
for(TreeIterator iter = EcoreUtil.getAllContents(rootObject); iter.hasNext();)
...
The problem is, how can I access the root object from the derivedThingsImpl ?! is there something like getRootObject() ?!
Thanks
UPDATE:
EObject e = this;
while(e.eContainer() != null) {
e = e.eContainer()
if (e instanceof RootElement)
break;
}
// No I should have the root element. Is this a good and clean way ?!
There is a better way of doing it:
EcoreUtil.getRootContainer(eObject);
Related
I am trying to implement an algorithm in a special data structure in graph form. my goal ist to get all paths from leaf (Target element) to the root.
This is how the graph looks like the image below.
We need to remember all of the path that we had in order to traverse in all of the different ways on the graph, therefore only a states list isn't enough, we need a paths list. For every path we will make it longer by one if it has one parent and if it has two or more we will duplicate this list and add the parent to each one.
Well I am not great at Java and I can not run this code so I can't guarantee this will run but the algorithm is ok.
public static List<ARGState> getAllErrorStatesReversed(ReachedSet reachedSet) {
ARGState pIsStart =
AbstractStates.extractStateByType(reachedSet.getFirstState(), ARGState.class);
ARGState pEnd = targetStates.get(0);
List<List<ARGState>> results = new ArrayList<>();
List<List<ARGState>> paths = new ArrayList<>();
paths.add(new ArrayList<ARGState>(pEnd));
// This is assuming from each node there is a way to go to the start
// Go on until all the paths got the the start
while (!paths.empty()) {
// Expand the last path on your list
List<ARGState> curPath = paths.remove(paths.size() - 1);
// If there is no more to expand - add this path and continue
if (curPath.get(curPath.size() - 1) == pIsStart) {
results.append(curPath);
continue;
}
// Expand the path
Iterator<ARGState> parents = curPath.get(curPath.size() - 1).getParents().iterator();
// Add all parents
while (parentElement.hasNext()) {
ARGState parentElement = parents.next();
List<ARGState> tmp = new ArrayList<ARGState>(List.copyOf(curPath));
tmp.add(parentElement);
paths.add(tmp);
}
}
return results;
}
Hope you understand, more than welcome to ask.
Good Luck
I need to create a data structure in java which can represents hierarchy of data. Example use case is shown in the image below.
an organization hierarchy
In my case only the leaves level will have data, and the internal nodes should act like indexes. I should be able to get data from the data structure using multiple keys(Composite keys).
Is it okay to use nested maps, or should I implement an m way tree(B tree/B+ tree) for this use case.
If the structure of the nested data is constant you could use normal classes with properties.
If the structure is dynamic I would use Maps, the interface and ignore the implementation.
About using using a custom tree structure, if you can use classes, thats better. If you use Maps, I would start with a HashMap and if you find it to be a problem your can replace your Map to something else later.
Obviously you have to use Tree like data structure. Here is the sample code of that.
High level code idea
class Entity{
// declare you attributes and below two properties
List<Entity> children;
boolean isleafNode;// for parent node its 'false' and for leaf node it will 'true'
}
you can implement Trie for this use case. Iterate over composite key and return data if found.
class definition:
public class TrieNode {
private HashMap<String, TrieNode> children;
private Data data;
private boolean isLeaf;
// ...
}
find query will look like:
public Data find(List<String> compositeKey) {
TrieNode current = root;
for (String key: compositeKey) {
TrieNode node = current.getChildren().get(key);
if (node == null) {
return null;
}
current = node;
}
if(current.isLeaf()) {
return current.getData();
} else {
return null;
}
}
insert will look like:
public void insert(List<String> compositeKey, Data data) {
TrieNode current = root;
for (String key: compositeKey) {
current = current.getChildren()
.computeIfAbsent(key, c -> new TrieNode());
}
current.setLeaf(true);
current.setData(data);
}
I am trying to modify a field in select objects in a List but I am unable to find a way to do so, using plain Iterator because it has no set() method.
I tried using ArrayListIterator that provides a set() method, but this throws a casting exception. Is there way to workaround this?
Iterator it = topContainer.subList.iterator();
while (it.hasNext()) {
MyObject curObj = (MyObject) it.next();
if ( !curObj.getLabel().contains("/") ) {
String newLabel = curObj.getLabel() + "/";
curObj.setLabel(newLabel);
((ArrayListIterator) it).set(curObj)
}
}
I expect the original current object in the list to be set without incident, but instead I am getting this exception:
java.util.ArrayList$itr cannot be cast to
org.apache.commons.collections.iterators.ArrayListIterator
What is the proper way of accomplishing what I would like to do?
You do not need to call set at all. You can just call setLabel on curObj:
// please, don't use raw types!
Iterator<? extends MyObject> it = topContainer.subList.iterator();
while (it.hasNext()) {
MyObject curObj = it.next();
if ( !curObj.getLabel().contains("/") ) {
String newLabel = curObj.getLabel() + "/";
curObj.setLabel(newLabel);
}
}
The correct way would be following (works not for java versions below 1.5):
for(MyObject curObj : topContainer.subList){
if (!curObj.getLabel().contains("/")) {
String newLabel = curObj.getLabel() + "/";
curObj.setLabel(newLabel);
}
}
This is an enhanced for-loop, and it does call the iterator too, but you can't see it.
Also setting the object via the iterator is not needed, as you're working with references to Objects in Java, when you edit an object, everyone that has a pointer to that object, will see the change too. For more you can read this great post: Is Java “pass-by-reference” or “pass-by-value”?
If you can't use Java 5, then you're missing out big time. The current java version is 11. So you should really, really, really, upgrade your JDK
you just have to set the label. In JAVA 11 you can use streams. it makes your code more readable.
List<MyObject> list = topContainer.subList;
list
.stream()
.filter(Predicate.not(e->e.getLabel().contains("/")))
.forEach(e->e.setLabel(e.getLabel()+"/"));
In java 8 you can use
(!e->e.getLabel().contains("/"))
instead of
Predicate.not(e->e.getLabel().contains("/")
I'm using CheckedTreeSelectionDialog to implement some kind of refactoring. The refactoring is performed over a large set of objets, so each root node of the selection tree is a objet, and each of those objects has a suggested modification as a child node. For example,
CheckedTreeSelectionDialog:
ObjectA
---------- Remove attribute attA1
---------- Remove attribute attA2
Object B
---------- Remove attribute attB1
.
.
.
I obtain the selected elementes this way:
Object[] result = dialog.getResult();
and, if I select all those 5 elements showed before, I will get the list:
ObjectA
attA1
attA2
ObjectB
attB1
I thought I would get some kind of tree, for example, where I can get the object "ObjectA" and see which of its childs where selected.
Am I doing this right?
Thanks!
Alternatively you can get the tree viewer and from that get the checked elements.
Map<Object, List<Object>> mapOfCheckedElements = new HashMap<Object, List<Object>>();
for (TreeItem level1 : checkBoxTreeViewer.getTree().getItems()) {
if (level1.getChecked()) {
List<Object> checkedChildren = new ArrayList<Object>();
for (TreeItem level2 : level1.getItems()) {
if (level2.getChecked()) {
checkedChildren.add(level2);
}
}
mapOfCheckedElements.put(level1, checkedChildren);
}
}
I have a hashmap that is 101 keys in size, but I know for sure about 6 of those have no data inside, and there may be more without data as well. What exactly is inside the empty indexes? Is it null? or is there a Hash(index).isEmpty() method that I can use to see if its empty?
I realize there is a isEmpty method inside hashmap, but I thought that only checked if the entire map was empty not just a single index.
I realize there is a isEmpty method
inside hashmap, but I thought that
only checked if the entire map was
empty not just a single index.
I think what you're looking for is the containsKey(Object) method. According to the documentation:
Returns true if this map contains a
mapping for the specified key. More
formally, returns true if and only if
this map contains a mapping for a key
k such that (key==null ? k==null :
key.equals(k)). (There can be at most
one such mapping.)
Parameters:
key - key whose presence in this map is to be tested
Returns:
true if this map contains a mapping for the specified key
Well, for the keys to arrive there with no data, you have to put them there.
If you did map.put(key, null) then yes the data for that key is null. You always have to give the second parameter to the method, you can't just map.put(key).
If you know for sure that a certain key should have no data you could try going into debug mode and putting a watch for myMap.get(myEmptyKey) and see what you get (in case that no data is an empty object or something else, you should be able to see that).
Edit: Some code would be useful to help you, but if I understand correctly you do something like this:
for (Object obj : list) {
if (matchesCriteriaX(obj)) {
map.put("X", obj);
else if (matchesCriteriaY(obj)) {
map.put("Y", obj);
}
}
Well, if you do that and try to do map.get("X"), but you never actually put anything for that key (becaus no object matched criteria X), you will most definitely get back a null.
On the other hand, if you did something like
Map<String, List<Object>> map = new HashMap<String, List<Object>>();
map.add("X", new ArrayList<Object>());
map.add("Y", new ArrayList<Object>());
for (Object obj : list) {
if (matchesCriteriaX(obj)) {
List<Object> list = map.get("X");
list.add(obj);
else if (matchesCriteriaY(obj)) {
List<Object> list = map.get("Y");
list.add(obj);
}
}
then you could check if a category is empty by doing map.get("x").isEmpty() since List has that method (and it would be empty if no object matched the key criteria).
Judging from what you said, I'm suspecting something like this:
Map<SomeKey, List<SomeValue>> yourMap;
If this is the case, what you can do is
if( yourMap.contains(someKey) ){
List<SomeValue> someList = yourMap.get(someKey);
if(someList.size() == 0){
// it's empty, do something?
}
}