#java
#java
Вопрос:
У меня есть такой код:
List<Account> myAccounts = new ArrayList<>();
List<String> numbers = new ArrayList<>();
List<Account> resultList = new ArrayList<>();
for (String number : numbers) {
for (Account account : myAccounts) {
if(number.equals(account.getNumber())){
resultList.add(account);
}
}
}
Я попытался получить определенные учетные записи с указанными номерами, но я делаю это через цикл all numbers и сравниваю с номерами учетных записей. Как я могу сделать это в функциональном стиле? Я спрашиваю не о том, как превратить это в функцию, а о том, как получить те же результаты, не выполняя каждый раз два цикла.
Комментарии:
1. Вы спрашиваете, как превратить это в функцию или как получить те же результаты без необходимости запускать два цикла каждый раз, когда вы хотите проверить?
2. @NathanWalsh без необходимости запускать два цикла каждый раз
3. вы можете использовать streams api. Пример: Список<Целое число> список = новый ArrayList<>(); list.stream().filter( i -> true ).forEach( i -> list.add(i)); Или вы даже можете заменить forEach на просто collect
4. @merc-angel Что ты подразумеваешь под «без необходимости запускать два цикла каждый раз»? Вы имеете в виду, что вам не нужно перебирать все элементы для каждого элемента? Потому что ответ Наги почти ничем не отличается от вашего вложенного цикла с точки зрения производительности. Единственное отличие заключается в том, что он не продолжается после того, как найдено совпадение, но вы можете легко поставить знак
break
«если», чтобы добиться этого.
Ответ №1:
List<Account> myAccounts = new ArrayList<>();
List<String> numbers = new ArrayList<>();
List<Account> resultList = myAccounts.stream()
.filter(account -> numbers.contains(account.getNumber()))
.collect(Collectors.toList());
Вы можете использовать это. единственным требованием является то, что вы должны использовать как минимум Java8
Комментарии:
1. @merc-angel
numbers
, вероятно, должен быть aSet<String>
, поскольку наборы обычно оптимизируютcontains
метод больше всего. Например, сложность HashSet#contiains близка к O(1).2. 100% согласен с @Pshemo
Ответ №2:
Попробуйте сделать это так.
List<Account> results = numbers.stream().flatMap(numb -> myAccounts
.stream()
.filter(acct->numb.equals(acct.getNumber()))
.collect(Collectors.toList());
Ответ №3:
Лучший способ добиться этого — загрузить объекты вашей учетной записи в базу данных sql lite. (Или добавьте его в свою текущую базу данных, если она у вас уже есть)
https://developer.android.com/training/data-storage/sqlite
Затем, когда у вас есть все объекты учетной записи, хранящиеся в базе данных, вы можете просто написать запрос, чтобы перечислить учетные записи с соответствующими номерами.
Вот более полный пример того, как построить все, от создания базы данных до создания объектов и, в конечном итоге, запроса к ним.
https://www.androidauthority.com/creating-sqlite-databases-in-your-app-719366/
Ответ №4:
При функциональном подходе вы бы создали метод из вашего цикла for, как в:
public void compareNumbers(List<String> numbers, List<Account> resultList){
for (String number : numbers) {
for (Account account : myAccounts) {
if(number.equals(account.getNumber())){
resultList.add(account);
}
}
}
Комментарии:
1. Хорошо, но я имею в виду, как заменить цикл в цикле
2. Вы должны использовать циклы, иначе как вы собираетесь сравнивать значения?
3. Я думаю, что это можно сделать: D
4. Вы могли бы прочитать в lambda, если вам интересно. Но я не уверен, можете ли вы перебирать массивы с помощью lambda.
5. Streams api вот как, посмотрите на другие ответы. Он попросил функциональный подход, и это не работает.