Специфичный для Android объект поиска путем сопоставления свойств в коллекции по предикату - PullRequest
0 голосов
/ 29 сентября 2018

У меня есть коллекция из 10000 объектов, которые имеют два свойства: string и string[]

class Product
{
  String name;
  String[] aliases;
}

Каждый объект занимает примерно 64 байта, поэтому мы смотрим на мегабайт впамять для всей коллекции, которая кажется управляемой Android для поиска в памяти.

Я хочу получить точное совпадение либо с одной строкой, либо с любой строкой в ​​массиве, а затем вернуть свойство nameобъект.

Однако у android есть некоторые ограничения на Lambdas и .stream(), которые исключают многие популярные поисковые решения, не заставляя пользователей иметь ОС 7.0 или выше, что исключает примерно треть пользователей.Я бы хотел этого избежать.

В настоящее время работает следующий код, но он выглядит ужасно, учитывая некоторые варианты, которые я видел, которые используют потоки и лямбды.

public String isProductOrAlias(String lowertext) {
    //products is instantiated in the parent class 
    //as a List<Product> loaded into memory from a local file
    try {
        for (Product p: products) {
            if(lowertext.equals(p.name.toLowerCase()))
                return p.name;
            if(p.aliases != null) {
                for (String s: p.aliases) {
                    if(lowertext.equals(s.toLowerCase()))
                        return p.name;
                }
            }
        }
    } catch (Exception ex) {
        return "";
    }
    return "";
}

Как лучше всего достичь той же цели, учитывая ограничения окружающей среды?В идеале мы хотели бы сохранить minSDK до 23 (6.0) и выше.

1 Ответ

0 голосов
/ 29 сентября 2018

Canonical Kotlin, который будет работать на любой версии Android независимо от потоков Java, поскольку он не использует их:

data class Product(val name: String, val aliases: Array<String>)

// written as an extension function, but doesn't have to be...
fun List<Product>.isProductOrAlias(text: String): String {
   return this.firstOrNull { product -> 
       product.name.equals(text, ignoreCase = true) ||
       product.aliases.any { alias -> 
           alias.equals(text, ignoreCase = true)
       }
   }?.name ?: ""
}

fun test() {
   // assume somewhere this was created
   val products = listOf<Product>(...)

   println(products.isProductOrAlias("something")) // prints name of Product or ""
}

См. Справочник API Kotlin для стандартной библиотеки:

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...