I have some data and I have added them to Hashtable in some orders what I want to do now is to get the data in the same order that I have entered
What is the data type that I can use?
Assuming your key is a String you could add some ordering to it and have a getter method for the sorted data. See example below:
static int order;
Hashtable map = new Hashtable();
void put (String key, Object value) {
map.put(order + key, value);
order++;
}
Enumeration getSorted() {
Enumeration keys = map.keys();
Vector sortedKeys = new Vector();
while (keys.hasMoreElements()) {
String key = (String) keys.nextElement();
insertionSort(key, sortedKeys);
}
Vector sortedData = new Vector();
keys = sortedKeys.elements();
while (keys.hasMoreElements()) {
String key = (String) keys.nextElement();
sortedData.addElement(map.get(key));
}
return sortedData.elements();
}
You can find insertionSort algorithms at http://en.wikipedia.org/wiki/Insertion_sort
A Hashtable does not retain any ordering.
If you need insertion order access see if Linked Hash Map is offered in JavaME
You can download a source code of Java SE and make work LinkedHashMap in J2ME easily by removing generics (but also you might need to perform this on it's parent classes and interfaces).
You can find LinkedHashMap for Java ME here
Related
I have the following enum in groovy
public enum ImageTypes {
jpg ("image/jpeg"),
jpeg ("image/jpeg"),
jpe ("image/jpeg"),
jfif ("image/jpeg"),
bmp ("image/bmp"),
png ("image/png"),
gif ("image/gif"),
ief ("image/ief"),
tiff ("image/tiff"),
tif ("image/tiff"),
pcx ("image/pcx"),
pdf ("application/pdf"),
final String value
ImageTypes(String value) {
this.value = value
}
String getValue() {
return this.value
}
String toString(){
value
}
String getKey() {
name()
}
}
and I want to produce an ArrayList<String> of the keys or the values
What I am currently doing is looping through all the items and building the array list, but I'm thinking there has got to be a simple way to do this...
def imageTypes = ImageTypes.values()
def fileExts = new ArrayList<String>()
def mimeTypes = new ArrayList<String>()
for (type in imageTypes) {
fileExts.add(type.key)
mimeTypes.add(type.value)
}
ArrayList of keys
ImageTypes.values()*.name()
ArrayList of values
ImageTypes.values()*.value
There are two things to point out here.
1) I'm using the spread operator to call an action on each entry in a collection (although this case it's just an array), that's how the name() and value references are used.
2) I'm calling name() with parenthesis (as a method) because (I believe) it is an implicit attribute on the enum, whereas I'm just using the value attribute directly from the ImageTypes object for the values.
Expanding #mnd's answer -
The Spread Operator is the best choice, but if you're using Jenkins this won't work as is. To run the Spread Operator you will need to add #NonCPS in the Jenkins Pipeline DSL.
Another way to the list of enum keys is to directly use its Enumeration features.
ImageTypes.values().collect() { it.name() }
I have been following following coreclr for a little while and I am new to programming. My question is why do they pass interfaces into Dictionary's especially the key value?
//
// Allocate a new Dictionary containing a copy of the old values, plus the new value. We have to do this manually to
// minimize allocations of IEnumerators, etc.
//
Dictionary newValues = new Dictionary(current.m_localValues.Count + (hadPreviousValue ? 0 : 1));
My understanding is that interface is to implemented by a class. Once implemented it can call/use functions or store data in the classes properties/ variables. I am missing some understanding of interfaces and their use cases but I do not know what that it.
Why do you instantiate a variable to an interface or pass an interface into a parameter? My understanding is you will then have an instance of that variable which still can't hold values nor change state through methods.
Let me explain.
Interface is contract. It just contains method without implementation. Now it may possible that that interface is being implemented by any number of class.
public interface IEntity { int Id {get;set;} }
public class Student : IEntity { public int Id {get;set;} // Interface Property }
public class Teacher : IEntity { public int Id {get;set;} // Interface Property }
Dictionary<IEntity,object> obj = new Dictionary<IEntity,object>(); Student s = new Student(); Teacher t = new Teacher(); obj.Add(s,any object); obj.Add(t,any object);
This is because of interface that your dictionary can hold reference of both type ( Student and Teacher).
In .NET when any object is created it is uniquely identify by GetHashCode() method. // You can find more detail on this on MSDN.
Also Dictionary not means that keys must be only primitive type. This is the reason it is good if you have more than one key ( Like composite key in Database) so it allow you to identify uniquely based on your custom implementation.
Now second Generic.
public class PersonInfo<T> where T : IEntity
{
public string Name {get;set;}
public T Entity {get;set;}
}
PersonInfo<Student> student = new PersonInfo<Student>();
student.T = new Student();
student.Name = "";
PersonInfo<Teacher> Teacher = new PersonInfo<Teacher>();
teacher.T= new Teacher();
teacher.Name = "";
When you have interface. It not actually interface. You always have a reference to object with that interface. And that object is the one responsible for comparison in dictionary
The benefit is not difference from using class as a key. Dictionary can be used as list to iterate KeyValuePair to take key to do some operation. But using interface means you can store various type of class with same interface instead of just one type. Which is decoupled and more flexible
I have a Hashtable and I want to put check whether the Hashtable has key or not before adding a key in Hashtable. As adding a duplicate key in Hashtable throwing exception.
Basically I want to override Hashtable's virtual 'Add' method and put a check in it. I dont know how can I override Add method.
Please help me to write override method.
You can use ContainsKey.
Another way is to use the Item indexer-property which adds new keys and updates existing.
var ht = new System.Collections.Hashtable();
ht["test"] = "foo"; // added
ht["test"] = "bah"; // updated
However, you should consider to replace your old and redundant Hashtable with a generic Dictionary<Tkey, Tval>. Why?
The Add method of the Hashtable class is overridable. So try this:
class MyHashTable : Hashtable
{
public override void Add(object key, object value)
{
try
{
base.Add(key, value);
}
catch
{
// whatever
}
}
}
I'm using a Hazelcast IMap instance to hold objects like the following:
public class Report implements Portable, Comparable<Report>, Serializable
{
private String id;
private String name;
private String sourceId;
private Date timestamp;
private Map<String,Object> payload;
// ...
}
The IMap is keyed by the id, and I have also created an index on sourceId, as I need to query and aggregate based on that field.
IMap<String, Report> reportMap = hazelcast.getMap("reports");
reportMap.addIndex("sourceId", false);
I've been trying to use the Aggregations framework to count reports by sourceId. Attempt #1:
public static int reportCountforSource(String sourceId)
{
EntryObject e = new PredicateBuilder().getEntryObject();
Predicate<String, Report> predicate = e.get("sourceId").equal(sourceId);
Supplier<String, Report, Object> supplier = Supplier.fromPredicate(predicate);
Long count = reportMap.aggregate(supplier, Aggregations.count());
return count.intValue();
}
This resulted in a ClassCastException being thrown by the Aggregations framework:
Caused by: java.lang.ClassCastException: com.hazelcast.mapreduce.aggregation.impl.SupplierConsumingMapper$SimpleEntry cannot be cast to com.hazelcast.query.impl.QueryableEntry
at com.hazelcast.query.Predicates$AbstractPredicate.readAttribute(Predicates.java:859)
at com.hazelcast.query.Predicates$EqualPredicate.apply(Predicates.java:779)
at com.hazelcast.mapreduce.aggregation.impl.PredicateSupplier.apply(PredicateSupplier.java:58)
at com.hazelcast.mapreduce.aggregation.impl.SupplierConsumingMapper.map(SupplierConsumingMapper.java:55)
at com.hazelcast.mapreduce.impl.task.KeyValueSourceMappingPhase.executeMappingPhase(KeyValueSourceMappingPhase.java:49)
I then changed to use Predicates instead of PredicateBuilder().getEntryObject() for Attempt #2:
public static int reportCountforSource(String sourceId)
{
#SuppressWarnings("unchecked")
Predicate<String, Report> predicate = Predicates.equal("sourceId", sourceId);
Supplier<String, Report, Object> supplier = Supplier.fromPredicate(predicate);
Long count = reportMap.aggregate(supplier, Aggregations.count());
return count.intValue();
}
This resulted in the same ClassCastException.
Finally, I used a lambda to implement the Predicate interface in Attempt #3:
public static int reportCountforSource(String sourceId)
{
Predicate<String, Report> predicate = (entry) -> entry.getValue().getSourceId().equals(sourceId);
Supplier<String, Report, Object> supplier = Supplier.fromPredicate(predicate);
Long count = reportMap.aggregate(supplier, Aggregations.count());
return count.intValue();
}
This attempt finally works.
Question #1: Is this a bug in Hazelcast? It seems that the Aggregations framework should support a Predicate constructed from either Predicates or PredicateBuilder? If not, then a new type should be created (e.g., AggregationPredicate) to avoid this kind of confusion.
Question #2 (related to #1): Using the lambda Predicate results in the index I created not being used. Instead, each entry within the map is being deserialized to determine if it matches the Predicate, which slows things down quite a bit. Is there any way to create a Supplier from a Predicate that will use the index? (EDIT: I verified that each entry is being deserialized by putting a counter in the readPortable method).
this looks like a Hazelcast bug. I guess I never created a unittest to test a Predicate created by PredicateBuilder. Can you please file an issue at github?
Currently indexes are not supported on mapreduce, whatever you try. The indexing system will be rewritten in the near future to also support all kinds of non-primitive indexes like partial or stuff.
Another thing that is not yet available is an optimized reader for Portable objects which would prevent full deserialization.
I have a function that returns objects of different types based on the parameter passed to this function.
Is it possible to add these different object types to a collection based on some identifier in C# 4.0?
Usually we do something like this
List or List
but i want one collection which can add object of any type.
Instead of just making a List<object> like other posters are recommending, you may want to define an interface eg IListableObject that contains a few methods that your objects need to implement. This will make any code using these objects much easier to write and will guard against unwanted objects getting into the collection down the line.
Yes, it is called object. Eg:
var objlist = new List<object>();
objlist.Add(1);
objlist.Add(true);
objlist.Add("hello");
You could use object[], List<object>, ArrayList, IEnumerable, ... but if those types have a common base type it would be better to stick to a strongly typed collection.
Really your collection should be as specific as you can make it. When you say
objects of different types
Do these objects have anything in common? Do they implement a common interface?
If so you you can specialise the list on that interface List<IMyInterface>
Otherwise List<object> will do what you want.
Update
No, not really.
I'm sorry but I'm going to question your design.
If you have a collection of different objects, how do you decide how to use one of the objects?
You're going to have a large switch statement switching on the type of the object, then you cast to a specific object and use it.
You also have have a similar switch statement in your factory method that creates the object.
One of the benefits of Object Orientation is that if you design your objects correctly then you don't need to do these large "If it's this object do this.Method(), if it's that object do that.OtherMethod()".
Can I ask, why are you putting different objects into the same collection? What's the benefit to you?
If you want a collection which can add objects of any type then List<object> is the most appropriate type.
Collections in earlier versions of C# (not generics) can contain any kind of objects. If they're value type, they will be boxed into object.
When you need to use them, you can just cast it to the original type.
You may use List<Type> to hold the type information, if that's what you want. And Type[], Hashtable, etc. are also fine. You can use typeof operator to get the type or use Object.GetType().
Also check out Dynamic type.
http://msdn.microsoft.com/en-us/library/dd264736.aspx
It will basically do the same thing.
My Suggestion:
public class ParamValue
{
object value = null;
public ParamValue(object val)
{
value = val;
}
public string AsString()
{
return value.ToString();
}
public int AsInt()
{
return int.Parse(value.ToString());
}
public int? AsNullableInt()
{
int n;
if (int.TryParse(value.ToString(), out n))
{
return n;
}
return null;
}
public bool AsBool()
{
return bool.Parse(value.ToString());
}
public bool? AsNullableBool()
{
bool b;
if (bool.TryParse(value.ToString(), out b))
{
return b;
}
return null;
}
}
public class Params
{
Dictionary<string, object> paramCol = new Dictionary<string, object>();
public void Add(string paramName, object value)
{
paramCol.Add(paramName, value);
}
public ParamValue this[string paramName]
{
get
{
object v;
if (paramCol.TryGetValue(paramName, out v))
{
return new ParamValue(v);
}
return null;
}
}
}
Use param class as a collectio to your values, you can convert the return to every type you want.
You could use a Tuple of Genric Types
public Tuple<T, T> MySuperMethod()
{
int number = 1;
string text = "Batman";
return new Tuple<int, string>(number, text);
}
The .NET Framework directly supports tuples with one to seven
elements. In addition, you can create tuples of eight or more elements
by nesting tuple objects in the Rest property of a Tuple object.
https://msdn.microsoft.com/en-us/library/system.tuple(v=vs.100).aspx