Допустим, у меня 5 полок для книг. Так же имеется коллекция (Collection<String>)
с названиями книг. Каким образом я могу разделить эту коллекцию, чтобы на каждой полке было приблизительно равное количество книг? То есть разделить эту коллекцию на 5 частей. Может подскажете методы, примеры алгоритмов?
Можно еще сделать через Stream
:
public static <T> Stream<Collection<T>> chunked(Stream<T> stream, int chunkSize) {
AtomicInteger index = new AtomicInteger(0);
return stream.collect(Collectors.groupingBy(x -> index.getAndIncrement() / chunkSize))
.entrySet().stream().map(Map.Entry::getValue);
}
А дальше использовать так:
Collection<String> str = List.of("1", "2", "3", "4", "5");
Stream<Collection<String>> chunked = chunked(str.stream(), 2);
chunked.forEach(System.out::println);
Вывод:
[1, 2]
[3, 4]
[5]
Наверное, можно как-то так.
+1
, где +1
добавляем столько раз, сколько у нас остаток в п.1 получился.List<String> initialCollection = new ArrayList<String>();
for(int i = 0; i < 31; i++) {
initialCollection.add("" + i);
}
List<List<String>> resultCollections = new ArrayList<>();
int remainder = initialCollection.size() % 5;
int minimumCollectionSize = initialCollection.size() / 5;
for (int i = 0; i < 5; i++) {
int startIndex = i * minimumCollectionSize;
int endIndex = (i + 1) * minimumCollectionSize;
if (i < remainder) {
startIndex += i;
endIndex += i + 1;
} else {
startIndex += remainder;
endIndex += remainder;
}
List<String> collectionPart = new ArrayList<>(initialCollection.subList(startIndex, endIndex));
System.out.println(collectionPart.size() + "/ " + collectionPart);
resultCollections.add(collectionPart);
}
System.out.println(resultCollections);
Проверить можно тут: https://ideone.com/u2UE4G
Можно пойти через нахождение остатка и использования ф-ции subList:
final int stairsCount = 3;
List<String> books = List.of("1", "2", "3", "4", "5", "6", "7", "8");
int residue = books.size() % stairsCount;
final int booksInEach = books.size() / stairsCount + (residue == 0 ? 0 : 1);
List<List<String>> stairsOfBooks = new ArrayList(stairsCount);
for(int i = 0; i < stairsCount - 1; i++){
stairsOfBooks.add(books.subList(i * booksInEach, i * booksInEach + booksInEach));
}
if(stairsCount != 0){
stairsOfBooks.add(books.subList((stairsCount - 1) * booksInEach, residue == 0 ? books.size() : (stairsCount - 1) * booksInEach + residue));
}
Убедиться в правильности можно поместив следующий код:
stairsOfBooks.get(stairsOfBooks.size() - 1).forEach(System.out::println);
System.out.println("---");
В концы блоков for
и if
.
public static void main (String[] args){
int countBookOnShelf = 5; //кол-во книг на полке
List<String> books = Arrays.asList("book1", "book2", "book3", "book4", "book5", "book6"); //список книг
List<List> shelfs = new ArrayList<>(); //полки
List<String> shelf = new ArrayList<>(); //полка наполняемая в данный момент
for(String book : books){
shelf.add(book);
//если кол-во книг на текущей полке превысило максимальное возможное кол-во книг на полке, то начинаем заполнять новую полку
if(shelf.size() == countBookOnShelf ){
shelfs.add(shelf);
shelf = new ArrayList<>();
}
}
if(shelf.size() > 0) shelfs.add(shelf);
System.out.println(shelfs);
}
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Я создал проект и после его сохранения и загрузки он перестал видеть директории и в том числе класс "main"
У меня вопрос про использование метода toString(), его переопределение На сколько я знаю, он используется для удобного вывода данных об объекте...
У меня в программе есть рекурсивный поиск и открытие файла, в обоих случаях программа зависает на время обработки, я пытался решить эту проблему,...