Difference between adt and data structures - data-structures

Stack is an example of an abstract data type, stack is an example of a data structure but yet abstract data types are different from data structures how come?

You can think of an ADT (Abstract Data Type) as collection of operations (i.e. add, remove, insert that define how the ADT behaves on a collection of data elements. At the ADT level, the exact way that the data is stored is hidden; hence the Abstract in Abstract Data Type. The big idea here is to hide the way data is presented to make it more accessible to others. Examples include Map and Que.
A data structure, on the other hand, actually implements those operations that define the ADT's behaviour. Examples include Array and List.
In more practical terms, you'll typically see an ADT defined in two files: 1) an interface file, which specifies the required operations; 2) an implementation file, which implements those operations using a specific data structure.
This is why you'll see something like public interface SomeList<T> at the head of interface files and public class SimpleLink<T> implements SomeList<T> at the head of implementation files — the implements is a "promise" to implement all of SomeList<T>'s methods.

Related

Data Structure - Abstract data type VS Concrete data type

Abstract data type (ADT) : Organized data and operations on this data
Examples : Stack, Queue
what's meaning of Concrete data type (CDT)?
please explain by Examples.
One way to understand it is that an ADT is a specification of an object with certain methods.
For example if we talk about a List we are referring to an object that performs list operations such as:
add to the beginning
add to the end
insert at position
size
etc..
A "concrete data type" in this context would refer to the actual Data Structure you use to implement the list.
For example, one implementation of a List is to create nodes with a value and next pointer to point to the next node in the list.
Another is to have a value array, and a next array to tell you where the next node is (this is a more popular implementation for parallelism).
And yet another is to have a dynamic array (known as an ArrayList in Java) where you use an array till it fills up and then you duplicate it's size and copy the values to the new array.
So the concrete data type refers to the data structure actually being used, whereas the ADT is the abstract concept like List, Dictionary, Stack, Queue, Graph, etc..
There are many ways to implement an ADT.

Why does Map<K,V> not extends Function<K,V>?

While playing around with the new Java 8 Stream API I got to wondering, why not:
public interface Map<K,V> extends Function<K, V>
Or even:
public interface Map<K,V> extends Function<K, V>, Predicate<K>
It would be fairly easy to implement with default methods on the Map interface:
#Override default boolean test(K k) {
return containsKey(k);
}
#Override default V apply(K k) {
return get(k);
}
And it would allow for the use of a Map in a map method:
final MyMagicMap<String, Integer> map = new MyMagicHashMap<>();
map.put("A", 1);
map.put("B", 2);
map.put("C", 3);
map.put("D", 4);
final Stream<String> strings = Arrays.stream(new String[]{"A", "B", "C", "D"});
final Stream<Integer> remapped = strings.map(map);
Or as a Predicate in a filter method.
I find that a significant proportion of my use cases for a Map are exactly that construct or a similar one - as a remapping/lookup Function.
So, why did the JDK designers not decide to add this functionality to the Map during the redesign for Java 8?
The JDK team was certainly aware of the mathematical relationship between java.util.Map as a data structure and java.util.function.Function as a mapping function. After all, Function was named Mapper in early JDK 8 prototype builds. And the stream operation that calls a function on each stream element is called Stream.map.
There was even a discussion about possibly renaming Stream.map to something else like transform because of possible confusion between a transforming function and a Map data structure. (Sorry, can't find a link.) This proposal was rejected, with the rationale being the conceptual similarity (and that map for this purpose is in common usage).
The main question is, what would be gained if java.util.Map were a subtype of java.util.function.Function? There was some discussion in comments about whether subtyping implies an "is-a" relationship. Subtyping is less about "is-a" relationships of objects -- since we're talking about interfaces, not classes -- but it does imply substitutability. So if Map were a subtype of Function, one would be able to do this:
Map<K,V> m = ... ;
source.stream().map(m).collect(...);
Right away we're confronted with baking in the behavior of what is now Function.apply to one of the existing Map methods. Probably the only sensible one is Map.get, which returns null if the key isn't present. These semantics are, frankly, kind of lousy. Real applications are probably going to have to write their own methods that supply key-missing policy anyway, so there seems to be very little advantage of being able to write
map(m)
instead of
map(m::get)
or
map(x -> m.getOrDefault(x, def))
The question is “why should it extend Function?”
Your example of using strings.map(map) doesn’t really justify the idea of changing the type inheritance (implying adding methods to the Map interface), given the little difference to strings.map(map::get). And it’s not clear whether using a Map as a Function is really that common that it should get that special treatment compared to, e.g. using map::remove as a Function or using map::get of a Map<…,Integer> as ToIntFunction or map::get of a Map<T,T> as BinaryOperator.
That’s even more questionable in the case of a Predicate; should map::containsKey really get a special treatment compared to map::containsValue?
It’s also worth noting the type signature of the methods. Map.get has a functional signature of Object → V while you suggests that Map<K,V> should extend Function<K,V> which is understandable from a conceptional view of maps (or just by looking at the type), but it shows that there are two conflicting expectations, depending on whether you look at the method or at the type. The best solution is not to fix the functional type. Then you can assign map::get to either Function<Object,V> or Function<K,V> and everyone is happy…
Because a Map is not a Function. Inheritance is for A is a B relationships. Not for A can be the subject of various kinds of B relationships.
To have a function transforming a key to its value, you just need
Function<K, V> f = map::get;
To have a predicate testing if an object is contained in a map, you just need
Predicate<Object> p = map::contains;
That is both clearer and more readable than your proposal.

How to extend Liquibase to generate change logs with stored procedures, functions and triggers?

Currently Liquibase has some limitations when you try to generate change logs on an existing database. It does not export the following types of objects:
Stored procedures, functions, packages
Triggers
Types
Reference: http://www.liquibase.org/documentation/generating_changelogs.html
As far as I understand I need to develop my own liquibase.snapshot.SnapshotGenerator implementation. I know how to obtain these types of objects from Oracle but I'm a bit lost on how to implement such interface from Liquibase.
Ideally I guess the liquibase.database.Database interface should be also extended to add the following extra methods:
public abstract boolean supportsPackages();
public abstract boolean supportsFunctions();
public abstract boolean supportsStoredProcedures();
public abstract boolean supportsTriggers();
public abstract boolean supportsTypes();
You are right that the general strategy is to create a new class that implements SnapshotGenerator, but there are a couple other steps you need to do as well. The general snapshot process is:
Liquibase searches for SnapshotGenerator implemetnations and calls the addsTo() for each object it finds in the database. For your types, you probably want a quick "if passed object instanceof Schema" because they are types that are part of a schema.
You will need to create new Package, StoredProcedure, etc objects that implement DatabaseObject. They will be lik ehte liquibase.structure.core.Table class and capture the state of the object. They are created in your SnapshotGenerator.addsTo() method to the point of being identifiable (name, schema, etc set)
All objects that are added by the addsTo() method are then ran through your SnapshotGenerator.snapshotObject() method which will pull any additional metadata that you didn't get originally, such as stored procedure text, etc.
Once liquibase has a snapshot containing your objects it compares the snapshot to another (in generateChangeLog case an empty snapshot) to determine what objects are missing, unexpected, and changed in the second snapshot. It then looks for implementations of MissingObjectChangeGenerator, UnexpectedObjectChangeGenerator, and ChangedObjectChangeGenerator. For generateChangeLog there will only be "missing" objects so you would implement MissingTriggerChangeGenerator, MissingPackagedChangeGenerator etc. Their job is to create Change instances to create the missing objects
The Msising*ChangeGenerator classes could return RawSqlChange instances or you could create new implementations of Change such as CreateTriggerChange.

Alternatives to testing private methods in TDD

I'm trying to use TDD when writing a class that needs to parse an XML document. Let's say the class is called XMLParser, and its constructor takes in a string for the path to the XML file to parse. I would like to have a Load() method that tries to load this XML into memory, and performs a few checks on the file such as file system errors, whether or not its an XML file, etc.
My question is about alternatives: I've read that it's bad practice to have private methods that you need to test, and that you should be able to just test the public interface and let the private methods do their thing. But in this case, this functionality is pretty important, and I don't think it should be public.
Does anyone have good advice for a scenario like this?
I suggest to redesign your architecture a bit. Currently, you have one high level class with low level functionality embedded. Split that into multiple classes that belong to different layers (I use the term "layer" very loosely here).
Example:
Have one class with the public interface of your current class. (-> High level layer)
Have one class responsible for loading files from disk and handling IO errors (-> Low level layer)
Have one class responsible for validating XML documents (-> Inbetween)
Now you can test all three of these classes independently!
You will see that your high level class will do not much more than just composing the two lower level classes.
Use no access modifier (which is the next up to private) and write the test in the same package.
Good OOD is important but for really important functionality testing is more important. Good practices are always only a guideline and they are good in the general scenario.
You could also try to encapsulate that specific file-checking behaviour in another object and have your parser instantiate it and use it. This is probably what I would do. In this way you could also even use this functionality somewhere else with minimal effort.
You can make a subclass as part of your test package that exposes public accessors to the private methods (which should then be protected).
Public class TestableClass : MyClass
{
public someReturnType TestMethod() {
return base.PrivateMethod();
}
}

Polymorphic HashTable like datastructure

I'm creating a client side cache object and one of the consumers of the cache needs a means of looking up data by type. Obviously I can't just have a map from class to data since that wouldn't retrieve subtypes of the class. Is there a 'standard' or well suited data structure for this kind of thing?
Instead of using a HashTable, it'd be easier to use a tree, since a tree would easily represent the type heirarchy.
If you key you HashMap by Class objects it will behave exactly as you expect it to. There will be no lookup on "subtype".

Resources