1

Can I create a case class usefull just for an Collecetion (read HashSet) and a class that extends this case class to store usefull information?

I mean something like this:

case class User(id: String)

class UserInfo(id: String) extends User(id) {

  var time = 0
  var sum = 0

}

I just want to use UserInfo to store information about an User inside an HashSet, but using the case class implementation with all usefull method already implemented for collection (aka equals and hashCode)

Following Yuval Itzchakov comment:

abstract class User(val id: String) {

  private var time = 0L
  private var sum = 0L

  def addTime(_time: Long) = time += _time
  def addSum(_sum : Long) = sum  += _sum 

  def getTime() = time 
  def getSum() = sum  

}

case class UserInfo(override val id : String) extends User(id)

private vars because I want to guarantee that I can just add information (same for getters)

Tizianoreica
  • 2,142
  • 3
  • 28
  • 43

1 Answers1

2

Mutability is a bad idea, and it should be avoided almost always. One way to do what you need while preserving immutability is with companion objects:

case class User(id: String, time: Long)

object User {
   def addTime(user: User, time: Long): User = user.copy(time = user.time + time)
}

val users = Set(User("John", 5), User("Mary", 10))
val sumTime = users.foldLeft(0L)((sum, user) => sum + user.time)
val usersWithTimeAdded = users.map(User.addTime(_, 2))
Vidya
  • 29,932
  • 7
  • 42
  • 70
  • Can I ask you a thing? What if I have a user "John". Now If I add to a `Set(User("John",2),User("John",4))` my Set will have 2 John Users, right? I don't want this. I need a single User John, and everytime I find new information about it, I need to add to John Instance – Tizianoreica Mar 07 '17 at 08:18
  • Lot of ways to handle that. One would be to use a `Map[String, User]`. Fetch the `User` value for "John"; add time to it; and produce a new map copy with the updated value with something like `map + ("John" -> newTime)`. Or if you want to get fancy, you can create a special function for that purpose--or even endow `Map` with that function through an implicit class--as described [here](http://stackoverflow.com/a/9004242/1347281). – Vidya Mar 07 '17 at 18:01
  • Yeah but I thought about that, but I ask unh for a set (I mean, I want to avoid a map, because User object already handle information by itself) – Tizianoreica Mar 07 '17 at 18:04
  • If you insist on `Set[User]`, you could `set.find(_.id == "John")` to find John, add time, and create a new copy with the updated `User`. – Vidya Mar 07 '17 at 18:37
  • Maybe I'm thinking in a wrong way. I posted this question also because I know case classes are perfect for collection. But I'd like to store some different information in the class, as you can see in my code my main target is to use just one kind of information of the user (id) to identify it (and this is because I'm using a case class with just an id string) but once got the user I want to update information about it. – Tizianoreica Mar 07 '17 at 18:41