Unable to iterate Java List in Scala - java

I'm using the Java Twitter4J library in a Scala project.
I'm calling the method
twitter.getFriendsStatuses()
This method returns a list of twitter4j.User objects containing statuses.
I try to iterate over them and it goes in an infinite loop over the first element:
val users:List[User] = twitter.getFriendsStatuses(userId, paging.getSinceId())
while( users.iterator.hasNext() ) {
println(users.iterator.next().getStatus())
}
Any ideas?

I guess users.iterator produces the new iterator each time it's evaluated. Try this:
val it = users.iterator
while(it.hasNext() ) {
println(it.next().getStatus())
}

If you use Scala 2.8, you could use JavaConversion to convert Java collection to Scala collection automatically.
Ex.
import scala.collection.JavaConversions._
// Java Collection
val arrayList = new java.util.ArrayList[Int]
arrayList.add(2)
arrayList.add(3)
arrayList.add(4)
// It will implicitly covert to Scala collection,
// so you could use map/foreach...etc.
arrayList.map(_ * 2).foreach(println)

What's wrong with just
users.foreach(user => println(user.getStatus()))
or even
users.map(_.getStatus()).foreach(println _)
or, if you're worried about traversing the collection twice
users.view.map(_.getStatus()).foreach(println _)
IOW: Why do you want to manage the iteration yourself (and possibly make mistakes), when you can just let someone else do the work for you?

I prefer scalaj-collection to scala.collection.JavaConversions. This makes the conversions explicit:
import scalaj.collection.Implicits._
val arrayList = new java.util.ArrayList[Int]
arrayList.add(2)
arrayList.add(3)
arrayList.add(4)
arrayList.asScala.map(_ * 2).foreach(println)
Available here: https://github.com/scalaj/scalaj-collection

I suggest using
scala.collection.JavaConverters._
and simply add .asScala to every object you wish to iterate

Related

How to convert java list to array in scala?

How to convert java.util.list[POJO] to Scala array[POJO]?
I tried list.toArray method but it gives array[object].
Can anyone help on this?
You have to create the target array first, and provide it as input for the toArray method:
list.toArray(Array.ofDim[POJO](list.size))
This API shifts all the problems with array instantiation from the toArray method to you, so it is your responsibility to make sure that POJO is either something concrete, or to provide a ClassTag.
You could also do the conversion in two steps, first using asScala from JavaConverters:
import scala.collection.JavaConverters._
and then invoking .toArray from the Scala API (unlike Java's API, it preserves the type):
list.asScala.toArray
Below code works for me:
applcation.conf
mydata.crypto {
ciphers = [
"TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384"
"TLS_DHE_RSA_WITH_AES_256_GCM_SHA384"
"TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384"
]
protocols = [
"TLSv1.2"
]
}
Sample code in scala
Reading as List:
val ciphersList = config.getStringList("mydata.crypto.ciphers")
val protocolsList = config.getStringList("mydata.crypto.protocols")
import scala.collection.JavaConverters._
val enableCiphersList = ciphersList.asScala.toArray
val enableProtocolsList = protocolsList.asScala.toArray
Now we can see "enableCiphersList" and "enableProtocolsList" are Array of Strings type.

Is there any replacement or alternative way for using scala.collection.TraversableOnce.mkString() method in java 7

I am able to use mkString method in scala successfully. But while trying to do it with java, there does not exist mkString method for java7. So is there any way by which i can do the same thing in java.
Below is my code for reference:
val records: util.List[Tuple2[Void, Array[AnyRef]]] = dataSource.collect
import scala.collection.JavaConversions._
for (record <- records) {
println(record.f1.mkString(","))
}
You can use Arrays.deepToString to get the string representation of your array elements.
List<Tuple2<Void, Object[]>> records= dataSource.collect();
Tuple2<Void, Object[]> record = records.iterator().next();
System.out.println(Arrays.deepToString(record.f1));

how to read a list of objects from the configuration file in play framework

How can i read a list of users from the configuration file in play framework?
i have tried doing something like this:
users=[{uid:123,pwd:xyz},{uid:321,pwd:abc}]
from the play application
List<Object> uids = Play.application().configuration().getList("users");
will give me this a list of objects, if I iterate through the list i get each object as
{uid=123,pwd=xyz} and {uid=321,pwd=abc}
at this point i don't know how i can elegantly get the value of the uid, i can do some hacky job as omit the first and last bracket and parse for the before after equal sign, but it would be too ugly! any idea? (the application is written in java)
thanks
A Scala implementation that avoids the deprecated getConfigList method would rely on retrieving a Seq[Configuration] as follows:
case class UserConfig(uid: Int, pwd: String)
val userConfigs: Seq[UserConfig] = configuration.get[Seq[Configuration]]("users").map { userConfig =>
UserConfig(userConfig.get[Int]("uid"), userConfig.get[String]("pwd"))
}
Since I had recently the same problem and this is still unanswered,
here is my suggestion:
List<User> users = getConfig().getConfigList("users").stream().map(
config -> new User(config.getString("uid"), config.getBoolean("pwd"))
).collect(Collectors.toList());
As far as I know there are no tuples or anything in Java, you need to use either an object or a list with two elements. I decided to go for an object here, you can also return a list.
A list of uid's sounds to me like:
# List of UID's
users=[123,456,789] // every number represents a UID
Then you can get this list as:
List<Object> uids = Play.application().configuration().getList("users");
And then do what you want with this:
for (Iterator<Object> iterator = uids.iterator(); iterator.hasNext();) {
Object object = (Object) iterator.next();
System.out.println(object);
}
Is this what you are looking for?
BTW, you can read more about Play Framework configuration options: http://www.playframework.com/documentation/2.1.0/Configuration

Decorating a Java library object with Scala

I'm relying on an old Java API that kinda sucks and loves to throw null pointer exceptions when data is missing. I want to create a subclass that has option type accessors but preserves the old accessors until I decide I need to create safe accessors for them. Is there a good way to create a subclass from a copy of the original object? I'd like to achieve something like the following:
SafeIssue extends Issue {
def safeMethod: Option[Value] = { //... }
}
val issue = oldapi.getIssue()
val safeIssue = SafeIssue(issue)
//Preserves issue's methods and data if I need them
val unsafeVal = safeIssue.unsafeMethod
val maybeVal = safeIssue.safeMethod
Why not try an implicit conversion instead? This works better with Java APIs that like to create their own objects. So you would
class SafeIssue(issue: Issue) {
def original = issue
def safeFoo = Option(issue.foo)
// ... You must write any of these you need
}
implicit def make_issues_safe(issue: Issue) = new SafeIssue(issue)
Then you can--as long as you've supplied the method--write things like
val yay = Issue.myStaticFactoryMethodThing.safeFoo.map(x => pleaseNoNull(x))
(You can then decide whether you want to carry SafeIssue or Issue around in your code, and you can always get back the Issue from SafeIssue with the exposed original method (or you could make the issue parameter a val.)

How can I modify or remove properties values? - Jena API

I'm using Jena. I would like to know if there is a method that allows to modify or remove properties values of an instance?
Thanks
Statements in Jena are, by design, immutable. To change the value of a property p of some subject s, you need to add a new statement with the same subject and predicate, and remove the old statement. This is always true in Jena, even if the API sometimes hides this from you. For example, OntResource and its subclasses have a variety of setProperty variants, but under the hood these are performing the same add-the-new-triple-and-delete-the-old process.
It depends which Jena API you are using. For instance, if you are using Jena 3.0 and the Model API, you can use Model.remove(Statement) to remove a property by choosing the appropriate subject/predicate/object for the Statement. Modification can be achieved by removing the old version of a Statement and adding the new version.
To only remove the statement itself, i.e. the relation between the instance and the property value, you can use:
OntResource.removeProperty(Property, RDFNode)
If you want to remove the property value altogether, i.e. the value and all relations to it, you can use: OntResource.remove()
I had the similar task: I need to delete the property with the specified value. Hope the following code snippet will help someone.
public void removeLabel(String language, String value) {
NodeIterator nodeIterator = resource.getModel().listObjectsOfProperty(RDFS.label);
RDFNode foundToDelete = null;
while (nodeIterator.hasNext()) {
RDFNode next = nodeIterator.next();
boolean langsAreIdentical = next.asLiteral().getLanguage().equals(language);
boolean valuesAreIdentical = next.asLiteral().getLexicalForm().equals(value);
if (langsAreIdentical && valuesAreIdentical) {
foundToDelete = next;
break;
}
}
resource.getModel().remove(resource, RDFS.label, foundToDelete);
}

Categories