0

I have a Scala collection history as follows:

import scala.collection.mutable.{Map => mm, Set => mSet}
private var history: mm[Int, mSet[String]] = mm[Int, mSet[String]]()

And getHistory() Scala function returns history to type mm[Int, mSet[String]]. This is the Java code that stores the return value of history.

import scala.collection.mutable.Map;
import scala.collection.mutable.Set;
??? history = Database.getHistory();

The issue is that only Map<Object, Set<String>> causes no error. I tried with Map<Integer, ...> and Map<scala.Int, ...>, but nothing works.

Why is this error? I need to get the keys as a set (or iterator) of Integers so that I can iterate over/sort them.

enter image description here

prosseek
  • 182,215
  • 215
  • 566
  • 871
  • Show us the `getHistory` function? (with a return type annotation on it) – Chris Martin Aug 23 '15 at 01:27
  • @Chris Martin: It's just one line "history", and the type of history is mm[Int, mSet[String]] where mm is mutable Map, and mSet is mutable Set. – prosseek Aug 23 '15 at 01:34
  • Without being able to see the context, we can't be sure what the inferred return type is. Showing more code would help. – Chris Martin Aug 23 '15 at 01:51

3 Answers3

2

The problem is that the Java "foreach" loop is only coded to handle Java iterable types, and doesn't recognise a Scala Set as something it can iterate over. You can try an old-style for loop calling iterator, next, etc explicitly yourself, or convert the collection to a Java equivalent first (probably more easily done in the Scala code, though).

Shadowlands
  • 14,994
  • 4
  • 45
  • 43
1

This is a thing.

Coercing in Scala works fine, as noted:

  import scala.collection.JavaConverters._
  private var history: mm[Int, mSet[String]] = mm[Int, mSet[String]]()
  history += ((42, mSet("hi")))
  def getMystery(): java.util.Map[Int, mSet[String]] = history.asJava
  def getHistory() = history.asJava.asInstanceOf[java.util.Map[Integer, mSet[String]]]
som-snytt
  • 39,429
  • 2
  • 47
  • 129
0

JavaConversion can convert the keySet() into iterables.

    Map<Object, Set<String>> history = Database.getHistory();

    Iterable<Object> keys = JavaConversions.asJavaIterable(history.keySet());

    for (Object key : keys) {
        int k = (int)key;
        System.out.printf("%d-%s\n", k, history.get(k).get().toString());
    }

For Int issue, I could change the scala.Int to java.Integer in Scala code, but Object seems to be working fine.

For sorting keys, from the hint from Fastest way to get a sorted array out of an Iterable of integers, I can just populate the keys.

    List<Integer> sortedList = new ArrayList<>();
    for (Object i : keys) {
        sortedList.add((int)i);
    }
    Collections.sort(sortedList);

    for (int key : sortedList) {
        System.out.printf("%d-%s\n", key, history.get(key).get().toString());
    }
Community
  • 1
  • 1
prosseek
  • 182,215
  • 215
  • 566
  • 871