I thought this would be simple to implement, but it's starting to be a pain.
I've got a ArrayWritable subclass like so:
public class VertexDistanceArrayWritable extends ArrayWritable {
public VertexDistanceArrayWritable() {
super(VertexDistanceWritable.class);
}
public VertexDistanceArrayWritable(VertexDistanceWritable[] v) {
super(VertexDistanceWritable.class, v);
}
}
And a Writable subclass like so:
public class VertexDistanceWritable implements Writable {
//Implements write, readFields, and some custom functions that aren't used yet
}
In my Giraph compute function, Messages are VertexDistanceArrayWritable's. I want to iterate through every VertexDistanceWritable every message (VertexDistanceArrayWritable). Here is my compute function:
#Override
public void compute(Vertex<Text, MapWritable, FloatWritable> vertex,
Iterable<VertexDistanceArrayWritable> messages) throws IOException {
for(VertexDistanceArrayWritable message : messages) {
for(VertexDistanceWritable distEntry : message) {
//Do stuff with distEntry
}
}
//do other stuff
vertex.voteToHalt();
}
When I compile the code, I get this error:
for-each not applicable to expression type
for(VertexDistanceWritable distEntry : message) {
required: array or java.lang.Iterable
found: VertexDistanceArrayWritable
So now I have a problem. I want to iterate over the arrayWritable sub-class.
I've tried the following:
Change that line to for(VertexDistanceWritable distEntry : message.toArray()) which tells me that for-each not applicaable to type Object (required: array or java.lang.Iterable, found: Object).
Change that line to for(VertexDistanceWritable distEntry : message.get() ), which gives me error: incompatible types -- required: VertexDistanceWritable, found: Writable. This is the strangest problem -- VertexDistanceWritable extends Writable, shouldn't this work fine?
Writing my own custom "get_foo()" function for VertexDistanceWritable, which returns values as a VertexDistanceWritable[]. Of course, values is private, and has no getter function according to the documentation other than get() which I'm already having problems with
I just want a way to iterate over my VertexDistanceArrayWritable class. Is this even possible in Hadoop? It has to be, right? I should be able to iterate over a bunch of elements I made in an array, no? It seems like pretty darn basic stuff.
After about 30 minutes of experimenting and googling, I found out a clue here. Sort of cheesy, but it seems to compile correctly. Basically just use a Writable then cast it to my custom writable.
for(VertexDistanceArrayWritable message : messages) {
for(Writable distWritable : message.get()) {
vertexDistanceWritable distEntry = (VertexDistanceWritable) distWritable;
//do other stuff
}
}
I haven't yet confirmed if it works correctly, I will update and confirm my answer when I can make sure it works.
edit: it works. Might require a copy constructor since I had one for VertexDistanceWritable, but never checked that out.
Related
Now I want to send the message to the people which may be student,teacher or schoolmaster,and all of them have the phone,name and availdSendMsgCount.Before send the message which means insert the data to database,I have to judge whether them can be sent or not.So I write the code like this:
if(sendType=SendType.student){
List<Student> students=tStudentServiceImpl.queryByParam(conditionMap);
sendPhoneCout=students.size();
checkSendNumber(availdSendMsgCount,sendPhoneCout);
Log log=logMsgSend(content,sendPhoneCout,sendType);
for (Student vo : students)
sendMsgItem(content,vo.getPhone(),vo.getName(),vo.getId(),log.getId());
}
else if(sendType=SendType.teacher){
List<Teacher> teachers=tTeacherServiceImpl.queryByParam(conditionMap);
sendPhoneCout=teachers.size();
checkSendNumber(availdSendMsgCount,sendPhoneCout);
Log log=logMsgSend(content,sendPhoneCout,sendType);
for (Teacher vo : teachers)
sendMsgItem(content,vo.getPhone(),vo.getName(),vo.getId(),log.getId());
}
else{
List<Schoolmaster> schoolmasters=tSchoolmasterServiceImpl.queryByParam(conditionMap);
sendPhoneCout=schoolmasters.size();
checkSendNumber(availdSendMsgCount,sendPhoneCout);
Log log=logMsgSend(content,sendPhoneCout,sendType);
for (Schoolmaster vo : schoolmasters)
sendMsgItem(content,vo.getMasterPhone(),vo.getMasterName(),vo.getId(),log.getId());
}
I think this code is bad.But how to optimize?
I suggest you to create an interface and implement it in your dao classes, so each of them will behave differently.
public interface NameMe {
void sendMsgItem(content, Integer logId); // it's not clear the type of content
}
There is the method
// replace T with type of 'conditionMap' object, it's not clear from your code
public static void getAndSendMessageItems(Function<T, List<NameMe>> serviceFunc,
T conditionMap, Integer availdSendMsgCount, SendType sendType) {
List<NameMe> values = serviceFunc.apply(conditionMap);
Integer sendPhoneCout = values.size();
checkSendNumber(availdSendMsgCount, sendPhoneCout);
Log log = logMsgSend(content, sendPhoneCout, sendType);
for (NameMe i : values) {
i.sendMsgItem(content, log.getId());
}
}
And call it in your if/else
Function<T, List<NameMe>> serviceFunc = null;
if (SendType.student.equals(sendType)) {
serviceFunc = tStudentServiceImpl::queryByParam;
} else if (SendType.teacher.equals(sendType)) {
serviceFunc = tTeacherServiceImpl::queryByParam;
} else {
serviceFunc = tSchoolmasterServiceImpl::queryByParam;
}
getAndSendMessageItems(serviceFunc, conditionMap, availdSendMsgCount, sendType);
However, if your services implement the same interface, you even don't need to use Function<T, List<NameMe>>, you can just pass service via interface object.
Hope it helps!
When Schoolmaster, Teacher and Student implement the same interface or superclass then you could write one method with List as parameter which is doing all the stuff and that is called in each of your three cases.
On the other hand, why do you have three different classes? They seem to have exactly the same methods. Wouldn't one be enough with a type parameter that is deciding what kind of type it is?
What is the best way to treat a single object as iterable?
For example, in the following case...
public void fun(Object o) {
fun(new TempList(o));
}
public void fun(Iterable<Object> os) {
try {
for(Object o : os)
// Write to server
System.out.println(o);
} catch(Exception e) {
// log e
}
}
UPDATE:
Rewording this part.
A function already exists that takes an iterable of things and processes them (fun(Iterable<Object> os)). I am adding an alias for this function that takes a single item instead (fun(Object o)). This function will be called a lot by different instances, so I want the most resource efficient way to call the Iterable function with a single item (whatever creates the least trash/gets cleaned up the fastest).
Or, exactly as the question title says, What is the best way to pass an Object to a function that requires an Iterable<Object>?
Use Collections.singleton(item)
Maybe you can have a look on Collections.singletonList(object).
We have a huge project where many methods have been declared upfront and implementations are in progress. All declared methods have a body which simply throws an exception, say, UnimplException.
Now since the methods have been declared and a valid (compilable) body has been provided, they can be called from within other methods.
Now the question is that is there any way to list all such unimplemented (having just a compilable body throwing a particular exception) methods given a particular method?
To illustrate more(the code is to convey the idea and not strictly compiler friendly):
class A {
methA () {
throw new UnimplException();
}
}
class B {
methB () {
// proper body
// and calls methA
A.methA();
// does something else
// and returns.
}
}
class C {
methC () {
// proper body
// calls methB
B.methB();
}
}
So, if we start from, say, methC, then we want to travel all the way down the method tree to reach to methA because methC calls methB (which is properly implemented and we are not interested) which in turn calls methA which is not properly implemented and that is what we want to find.
We want to search for all such unimplemented methods starting from a method and going few levels deep until we cover all such unimplemented methods.
We thought of JavaAssist but we aren't sure how to go down all the levels because it seems to be giving us all methods called from within a method but not recursively.
Any help is greatly appreciated :)
Have you seen this project: https://github.com/gousiosg/java-callgraph? This appears to do the Java introspection part, listing every method call from every method in a jar file. I'd try using that to do the heavy lifting of parsing your code, then just recurse through the results.
Something like:
Use the callgraph code to build a list of all method calls.
Save that data somewhere.
Recursively parse that structure to find matching methods.
So from your example, step 1 would give something like the following:
A:methA -> UnimplException:<init>
B:methB -> A:methA
C:methC -> B:methB
Then shove those in a Multimap and do a fairly straightforward recursive search:
// this is populated from the output of the callgraph code
com.google.common.collect.Multimap<String, String> methodMap;
void checkAllMethods() {
for (String method : methodMap.keySet()) {
List<String> callStack = new ArrayList<>();
if (doesMethodThrowUnimplException(method, callStack)) {
System.out.println(method);
// can print callStack too if interested
}
}
}
boolean doesMethodThrowUnimplException(String method, List<String> callStack) {
for (String child : methodMap.get(method)) {
// have to check the exact method name from callgraph
if (child.equals("UnimplException:<init>")) {
return true;
}
// recurse into child if not already seen
if (!callStack.contains(child)) {
callStack.add(child);
if (doesMethodThrowUnimplException(child, callStack)) {
return true;
}
callStack.remove(callStack.size() - 1);
}
}
return false;
}
Doesn't strictly satisfy your requirements as this will report any method which throws the UnimplException, not those who only throw the exception, but not sure if that matters.
Standard disclaimer - just typed this in - haven't compiled / run it, so may well be typos, but hopefully the idea helps.
I store a list of models in Http.context, then I'm not able to loop through it in the view.
Index action :
#With(MembershipAction.class)
public static Result index() {
...
Action composition :
public class MembershipAction extends Action.Simple {
#Override
public Result call(Context ctx) throws Throwable {
Member member = Membership.getUser();
if (member != null) {
// MGroup.findInvolving(member)= List<play.db.ebean.Model>
// code : find.where().eq("members.id", member.id).findList();
ctx.args.put("groups", MGroup.findInvolving(member));
}
return delegate.call(ctx);
}
}
Template view #1 :
#ctx().args.get("groups")
Output :
BeanList size[6] hasMoreRows[false] list[models.MGroup#51, models.MGroup#3d, models.MGroup#2a, models.MGroup#29, models.MGroup#15, models.MGroup#1]
Template view #2 (not working) :
#for(group <- ctx().args.get("groups") ){
#group.name
}
Output :
Compilation Error / value map is not a member of Object
NOTE :
The method described here didnt work either : How to avoid passing parameters everywhere in play2?
Trying the snippet "#Menus" was unknown...
ctx().args gives you a map of Strings to Objects. So when you get something from this map, it's of type Object. I think your template fails compilation because you're trying to loop over an object.
The quickest way to fix this is to perform a cast in your template:
#for(group <- ctx().args.get("groups").asInstanceOf[List[models.MGroup]]) {
#group.name
}
In my opinion the better fix would be to:
Change your template #2 to take in a list of model objects as an input parameter. Take a look at the template syntax in the Play documentation, and in particular how to define template input parameters.
Change the Java actions that render this template to get the list of model objects from the HTTP context in Java-land, passing them into the template at render time (after doing some null checking and type checking).
This way the code is more robust to data not being in the context, and also you maintain type safety in your template. Since the list would be fed into your template as an input parameter, you wouldn't need to look in ctx().args in your template, and you thus wouldn't need to perform a cast.
I have a scala function with the following signature:
def getValue: Validation[ Throwable, String ]
Now, I want to process in Java the result (say res) of calling this function.
I can call res.isSuccess() and res.isFailure() but how do I extract the underlying Throwable or success String ?
I tried casting but testing (res instanceof scalaz.Failure) results in a scalaz.Failure cannot be resolved to a type (the scala and scalaz jars are visible)
Is there a generic way of doing this for Validation, Option, Either, etc... ?
EDIT I realize I can probably use a fold but that would lead to a lot of ugly boilerplate code in Java (which does not need more). Anything better looking ?
Success and Failure are both case classes:
final case class Success[E, A](a: A) extends Validation[E, A]
final case class Failure[E, A](e: E) extends Validation[E, A]
So you can write the following, for example:
import scalaz.*;
public class Javaz {
public static void main(String[] args) {
Validation<Throwable, String> res = new Success<Throwable, String>("test");
if (res.isSuccess()) {
System.out.println(((Success) res).a());
} else {
System.out.println(((Failure) res).e());
}
}
}
For Option and Either you can use the get method (after taking the left or right projection in the case of Either).
If at all possible it's probably cleaner to do this kind of unwrapping with a fold, etc. on the Scala side, though.