Reputation: 31
I'm trying to data from my server put them in my app, using RecyclerView and volley, now because of that I'm using an adapter and this is my adapter class
class TypeAdapter(var con: Context, var list: ArrayList<TypeItems>) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
override fun onBindViewHolder(p0: RecyclerView.ViewHolder, p1: Int) {
(p0 as ItemView).bind(list[p1].cartype, list[p1].typetype, list[p1].modeltype, list[p1].photype)
}
override fun onCreateViewHolder(p0: ViewGroup, p1: Int): RecyclerView.ViewHolder {
val v= LayoutInflater.from(con).inflate(R.layout.car_model_item, p0, false)
return ItemView(v)
}
override fun getItemCount(): Int {
return list.size
}
class ItemView(itemVeiw: View) : RecyclerView.ViewHolder(itemVeiw) {
fun bind(car_type: String, type: String, modele: String, ph: String) {
Picasso.with(itemView.context).load(ph).into(itemView.type)
itemView.name.text= "$car_type $type"
itemView.model.text= modele
}
}
}
and this is my TypeItems class
class TypeItems(car_typetype: String, typetype: String, modeletype: String, phtype: String) {
var cartype:String = car_typetype
var typetype:String = typetype
var modeltype:String = modeletype
var photype:String = phtype
}
and this is my main class
class CarModelActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_car_model)
val list= ArrayList<TypeItems>()
val rq= Volley.newRequestQueue(this)
val url= ("http://test123456789.cf/sell_items/reportall.php?car_type=${car_item.cartype}").replace(" ", "%20")
val srr= StringRequest(Request.Method.GET, url ,
Response.Listener { response ->
//converting the string to json array object
val array = JSONArray(response)
list.clear()
//traversing through all the object
for (i in 0 until array.length()) {
//getting item object from json array
val product = array.getJSONObject(i)
//ex Image
var url2= "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRj3LA1ERJCx8lM-qHsgaW_5IgzeW21w-Ona7iI05E9aoXrImtl"
//adding the product to item list
list.add(
TypeItems(
product.getString("car_type"),
product.getString("type"),
product.getString("model"),
url2
)
)
}
//creating adapter object and setting it to recyclerview
val adapter = TypeAdapter(this.applicationContext, list)
rv.layoutManager= GridLayoutManager(this, 2)
rv.adapter = adapter
}, Response.ErrorListener { error ->
Toast.makeText(this, error.message, Toast.LENGTH_LONG).show()
})
rq.add(srr)
}
}
now I want to remove the repeated items from my list, I want to sort by car_type and type and model, if the item is repeated, I want to remove it
Upvotes: 1
Views: 652
Reputation: 10704
Please note that the accepted answer suggests using list.contains(x)
before possibly adding the element to the list. However, contains
takes O(n) and you're doing that check for each item you get in response, so you'll have a total complexity of O(n^2). Performance could be quite bad if you have many items, and this means your application could be unresponsive and UX could be affected. Moreover, items are ordered in insertion order, so we need to explicitly sort it in the desired order – adding at least another O(n*log(n)), which is though dominated by the previous O(n^2).
A TreeSet
could hence be a better fit for this particular use case – as suggested by @Rogue and @taha – since it automatically prevents duplicates, it has a complexity of O(log(n)) in insertion and it enforces some kind of sorting.
Here's an example of how to use it:
data class TypeItems(
val car: String,
val type: String,
val model: String,
val ph: String
)
fun main() {
// simulates a response from the server
val response = listOf(
TypeItems("carBBB", "typeBBB", "modelBBB", "phBBB"),
TypeItems("carAAA", "typeAAA", "modelAAA", "phAAA"),
TypeItems("carAAA", "typeAAA", "modelAAA", "phAAA"),
TypeItems("carCCC", "typeZZZ", "modelYYY", "phCCC"),
TypeItems("carCCC", "typeXXX", "modelWWW", "phCCC"),
TypeItems("carCCC", "typeXXX", "modelVVV", "phCCC")
)
// creates an empty TreeSet with the desired sorting
val set = TreeSet<TypeItems>(
Comparator.comparing(TypeItems::car)
.thenComparing(TypeItems::type)
.thenComparing(TypeItems::model)
.thenComparing(TypeItems::ph) // needed for "consistency with equals"
)
// add each element to the set, it'll handle duplicates
response.forEach { set.add(it) }
// do something with the resulting set: print each item on a new line
set.forEach {
println(it)
}
}
That'll print:
TypeItems(car=carAAA, type=typeAAA, model=modelAAA, ph=phAAA) // duplicate removed
TypeItems(car=carBBB, type=typeBBB, model=modelBBB, ph=phBBB) // car order enforced (as B > A)
TypeItems(car=carCCC, type=typeXXX, model=modelVVV, ph=phCCC) // type order enforced (as X > B)
TypeItems(car=carCCC, type=typeXXX, model=modelWWW, ph=phCCC) // model order enforced (as W > V)
TypeItems(car=carCCC, type=typeZZZ, model=modelYYY, ph=phCCC)
Upvotes: 0
Reputation: 559
You should use the data class. It will contain overriding equals()
method inside:
data class TypeItems(
val car_typetype: String,
val typetype: String,
val modeletype: String,
val phtype: String
)
After digging into this issue, I found, that you cannot call method get()
on the Set
collection. So, this code won't work:
(p0 as ItemView).bind(list[p1].cartype, list[p1].typetype, list[p1].modeltype, list[p1].photype)
Summarize, Set
won't help you. To solve your issue, you need just to invoke defensive check:
val typeItems = TypeItems(
product.getString("car_type"),
product.getString("type"),
product.getString("model"),
url2
)
if(!list.contains(typeItems)) {
list.add(typeItems)
}
Therefore, there is another way, to solve this issue:
instead of
val adapter = TypeAdapter(this.applicationContext, list)
invoke
val adapter = TypeAdapter(this.applicationContext, list.distinct())
Method distinct()
return you unique values of your list in the same order. Don't forget to make it data class though.
Upvotes: 2
Reputation: 771
replace val list= ArrayList<TypeItems>()
with val set = SortedSet<TypeItems>()
and override equals method of TypeItems:
override fun equals(other: Any?): Boolean {
if (other is TypeItems) {
other.cartype == this.cartype && ... // replace TypeItems fields
} else {
false
}
}
also if you want to be sorted , TypeItems has to implement Comparable
https://docs.oracle.com/javase/8/docs/api/java/util/SortedSet.html
Upvotes: 0