How to write this java builder with generics to scala? - java

I'm trying to write this java code in scala, but I am getting a compile error.
Document<String, String> doc = Document.<String, String>builder().id("newDocId").score(1d).build();
I am trying:
val doc = Document.<String, String>builder().id("newDocId").score(1d).build();
How do I convert this java generic usage?
I also tried Document[String, String] but I get an error sayingDocument is not a value.

Try this:
val doc = Document.builder[String, String]().id("newDocId").score(1d).build()
Scala uses square brackets for generics (and semicolons are optional). Also, the type parameters go to the method, not the object.

Related

Or operator inside When function Spark Java API

How to use Or operation inside when function in Spark Java API. I want something like this but I get a compiler error.
Dataset<Row> ds = ds1.withColumn("Amount2", when(ds2.col("Type").equalTo("A") Or ds2.col("Type").equalTo("B"), "Amount1").otherwise(0))
Can somebody guide me please with a sample expression.
You should use or method:
ds2.col("Type").equalTo("A").or(ds2.col("Type").equalTo("B"))
With equalTo isin should work as well:
ds2.col("Type").isin("A", "B")

xtext: How to use unknown types for generics in the JVM inferrer?

When I try to use unknown types in the JvmModelInferrer it works for simple types, but does not work for generic types.
Example:
val unknownRef = typeRef('com.tmtron.ex.xtext2.usage.Unknown')
members += domainObject.toField('simpleField', unknownRef)
val listRef = typeRef(typeof(List), unknownRef)
members += domainObject.toField('list', listRef)
Note: the type com.tmtron.ex.xtext2.usage.Unknown does not exist in the target project.
The generator will produce this code:
private com.tmtron.ex.xtext2.usage.Unknown simpleField;
private /* List<com.tmtron.ex.xtext2.usage.Unknown> */Object list;
So the generated code for the simpleField is correct (or at least what I expected).
But for the generic list the code that I expected is commented out, and Object is used instead.
Why does this happen / how can I avoid this?
typeRef('java.util.List<com.tmtron.ex.xtext2.usage.Unknown>') should work as expected in this case.

Deserialize/Parse JSON in Java

I am searching a good and dynamic way to parse JSON in Java.
I've seen things such as:
List<String> list = new ArrayList<String>();
JSONArray array = obj.getJSONArray("test");
for(int i = 0 ; i < array.length() ; i++){
list.add(array.getJSONObject(i).getString("testKey"));
}
But that's not what I'm searching. In C# I had something like that:
dynamic results = JsonConvert.DeserializeObject<dynamic>(json);
info.Text = results["test"]["testKey"];
Here's an example of my JSON:
{"date":"07.05.2017 11:44",
"monday":{"1":{"subject":"test","room":"test","status":"test"}}}
So for example I would like to make:
results["monday"]["1"]["subject"];
I hope someone understands my problem and can help me.
Thanks in advance!
The core Java runtime does not offer a JSON parser (edit: technically, it does, see bottom of answer), so you will need a library. See Jackson, Gson, perhaps others.
Even with that, you will not get the dynamic features you want, because Java is statically typed. Example with Jackson:
ObjectMapper mapper = new ObjectMapper();
Map<String, Object> map = mapper.readValue(json, new TypeReference<Map<String, Object>>(){});
map.get("monday").get("1").get("subject");
^^^
This fails because the result of get("monday") is Object, not Map
The "right" approach in Java-land, would be to create a class (or set of classes) that represents your JSON model, and pass it to the JSON parser's "object mapper". But you said "dynamic" so I'm not exploring this here.
So you'll need to cast to Map when you know it's not primitive values:
((Map<String,Map<String,String>>)map.get("monday")).get("1").get("subject");
This works but with a warning about unchecked cast...
All in all, Java is not a dynamic language and I see no way to do exactly what you want (perhaps I'm missing approaches that are still slightly easier than what I have suggested).
Are you limited to Java-the-language or Java-the-platform? In the latter case you can use a dynamic language for the Java platform, such as Groovy, who has excellent features to parse JSON.
EDIT: a funny alternative is to use Java's own JavaScript implementation. This works and is easy and dynamic, but I don't know if it's "good":
String json = "{\"date\":\"07.05.2017 11:44\",\n" +
"\"monday\":{\"1\":{\"subject\":\"test\",\"room\":\"test\",\"status\":\"test\"}}}";
ScriptEngine engine = new ScriptEngineManager().getEngineByName("nashorn");
engine.put("data", json);
System.out.println(engine.eval("JSON.parse(data)['monday']['1']['subject']"));
If you are sure about the value you want to get then you can do following as well :
String str = "{\"date\":\"07.05.2017 11:44\", \"monday\":{\"1\":{\"subject\":\"test\",\"room\":\"test\",\"status\":\"test\"}}}";
JSONObject results= new JSONObject(str);
String str1 = results.getJSONObject("monday").getJSONObject("1").getString("subject");
System.out.println(str1);
For array kind of results, we have to write logic for that. In this case org.json library is used.
You can use GCON library:
https://github.com/google/gson
Very good for parsing JSON objects.

Scala - runtime String template

I want to do exactly what java's String Template does, but in scala. This library however does not work with case classes:
case class Obj(str:String)
val st = new ST("xx $obj.str$ xx",'$','$')
st.add("obj",Obj("replacement"))
st.render() //returns "xx xx"
ST tries to find property "str" with reflection, but it just does not work with scala.
How can I achieve it without ST?
Try to create your class like this:
case class Obj(#BeanProperty str: String)
Here is the scala doc: http://www.scala-lang.org/api/current/#scala.beans.BeanProperty
Also you can take a look at the project Scalasti which is a interface for StringTemplate: http://software.clapper.org/scalasti/
It's built into the language (in an extendable way). Just
val obj = Obj("replacement")
s"xx ${obj.str} xx"
You can have any Scala expression inside ${...}.
See http://docs.scala-lang.org/overviews/core/string-interpolation.html (or just search for "Scala string interpolation") for more.

Call Scala generic method from Java

How can I call the following Scala method from Java?
def mult[A,B: ClassTag,C: ClassTag](rdd1:RDD[A], rdd2:RDD[B])(implicit multiplier: Multiplier[A,B,C]): RDD[C] =
rdd1.zip(rdd2).map(p => multiplier.multiply(p._1, p._2))
Is it possible? Eclipse isn't giving me any help from its autocomplete.
Ugh. Must you? The B and C ClassTags are added to the list of implicit parameters (before the explicit ones), so you can add appropriate ones generated with the scala.reflect.ClassTag object. But it's going to be ugly.
Something like (untested):
mult(rdd1, rdd2, scala.reflect.ClassTag.apply(B.class), scala.reflect.ClassTag.apply(C.class), myMult);

Categories

Resources