Использование map в java

Проверьте, пуст ли массив

Это несложное задание, имея в виду, что мы можем использовать длина атрибут массивов:

boolean isEmpty = array == null || array.length == 0;

Кроме того, у нас также есть нулевой безопасный метод в ArrayUtils класс помощников, которые мы можем использовать:

boolean isEmpty = ArrayUtils.isEmpty(array);

Эта функция по-прежнему зависит от длины структуры данных, которая считает недействительными и пустыми под массивы как действительные значения тоже, так что нам придется следить за этими случаями края:

// These are empty arrays
Integer[] array1 = {};
Integer[] array2 = null;
Integer[] array3 = new Integer;

// All these will NOT be considered empty
Integer[] array3 = { null, null, null };
Integer[][] array4 = { {}, {}, {} };
Integer[] array5 = new Integer;

Типы массивов в Java

В Java есть несколько различных типов массивов, с которыми мы можем работать.

Одномерный массив является нормальным массив, который вы будете использовать наиболее часто. Этот тип массива содержит последовательные элементы одного типа, например список целых чисел.

Многомерный массив представляет собой массив из массивов. Двумерный массив — это массив, состоящий из нескольких одномерных массивов. Трехмерный массив — это массив, состоящий из нескольких двумерных массивов.

Массив объектов создаются так же, как массив примитивных типов данных.

ArrayList класс класс, который является изменяемым массивом. В то время как встроенные массивы имеют фиксированный размер, ArrayLists может динамически изменять их размер, поэтому элементы массива можно добавлять и удалять с помощью методов, как векторы в C ++.

Реализация

Поскольку Map является интерфейсом, вам необходимо создать конкретную реализацию интерфейса для его использования. API коллекций содержит следующие:

  • java.util.HashMap;
  • java.util.Hashtable;
  • java.util.EnumMap;
  • Jawakutilkidentity ः ashanap;
  • Jawakutilklaidaked ः ashanap;
  • java.util.Properties;
  • java.util.TreeMap;
  • java.util.WeakHashMap.

Наиболее часто используемые реализации – это HashMap и TreeMap. Каждая из них ведет себя немного по-разному в отношении порядка элементов при итерации карты и времени (большая запись 0), необходимого для вставки и доступа к элементам в картах.

  • HashMap отображает ключ и значение. Это не гарантирует какой-либо порядок элементов, хранящихся внутри карты.
  • TreeMap также отображает ключ и значение. Кроме того, он гарантирует порядок, в котором ключи или значения повторяются – это порядок сортировки.

Вот несколько примеров того, как создать экземпляр:

Map mapA = new HashMap();
Map mapB = new TreeMap();

Применение массивов

Как только массив инициализирован, можно задавать элементам значения при помощи индекса. Он определяет позицию каждого элемента внутри массива. Первый элемент занимает позицию , второй – 1 и так далее.

Важно отметить, что индекс первого элемента –. Обычно путаница возникает тогда, когда начинаешь думать, что раз в массиве 10 элементов, то их индексы будут перечисляться с 1 до 10

Но на самом деле счет идет от до 9. Например, возвращаясь к примеру с лотерей, можно создать массив из 6 элементов, и задать им числа из лотереи:

int[] lotteryNumbers = new int;
lotteryNumbers = 16;
lotteryNumbers = 32;
lotteryNumbers = 12;
lotteryNumbers = 23;
lotteryNumbers = 33;
lotteryNumbers = 20;

Сокращённый способ заполнения массива:

int[] lotteryNumbers = {16,32,12,23,33,20};

String[] names = {"John", "James", "Julian", "Jack", "Jonathon"};

Значения каждого элемента перечисляются внутри фигурных скобок. Порядок значений определяет, какое значение будет у каждого элемента, начиная с нулевой позиции.

Чтобы получить значение элемента, используется его индекс:

System.out.println("The value of the first element is " + lotteryNumbers);

Как определяется длина массива Java? Чтобы узнать  длину массива, в Java используется поле length:

System.out.println("The lotteryNumbers array has " + lotteryNumbers.length + " elements");

Примечание: распространена ошибка при использовании метода length, когда значение length используется как индексная позиция. Это всегда выдаст ошибку, так как индексные позиции массива , в то время как позиция length – 1.

Когда нужно использовать словари

Словари нужно использовать в следующих случаях:

  • Подсчет числа каких-то объектов. В этом случае нужно завести словарь, в котором ключами являются объекты, а значениями — их количество.
  • Хранение каких-либо данных, связанных с объектом. Ключи — объекты, значения — связанные с ними данные. Например, если нужно по названию месяца определить его порядковый номер, то это можно сделать при помощи словаря .
  • Установка соответствия между объектами (например, “родитель—потомок”). Ключ — объект, значение — соответствующий ему объект.
  • Если нужен обычный массив, но при этом максимальное значение индекса элемента очень велико, но при этом будут использоваться не все возможные индексы (так называемый “разреженный массив”), то можно использовать ассоциативный массив для экономии памяти.

Классы массивов и помощников

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

Обратите внимание, что основные операции, которые поддерживает массив, в определенном смысле ограничены. Это не редкость, чтобы увидеть сложные алгоритмы для выполнения относительно простых задач, когда дело доходит до массивов

По этой причине, для большинства наших операций, мы будем использовать помощник классов и методов, чтобы помочь нам: Массивы класс, предоставляемый Java и Apache ArrayUtils Один.

Чтобы включить последнее в наш проект, мы должны добавить Апач Викисклад зависимость:

org.apache.commonscommons-lang33.11

Мы можем проверить последнюю версию этого артефакта .

Карта массива к другому типу

Часто полезно применять операции на всех элементов массива, возможно, превращая их в другой тип объекта.

С этой целью, Мы постараемся создать гибкий метод помощников с использованием Generics:

public static  U[] mapObjectArray(
  T[] array, Function function,
  Class targetClazz) {
    U[] newArray = (U[]) Array.newInstance(targetClazz, array.length);
    for (int i = 0; i < array.length; i++) {
        newArray = function.apply(array);
    }
    return newArray;
},>,>

Если мы не используем Java 8 в нашем проекте, мы можем отказаться от Функциональные аргумент, и создать метод для каждого отображения, что мы должны выполнить.

Теперь мы можем повторно использовать наш общий метод для различных операций. Давайте создадим два тестовых случая, чтобы проиллюстрировать это:

@Test
public void whenMapArrayMultiplyingValues_thenReturnMultipliedArray() {
    Integer[] multipliedExpectedArray = new Integer[] { 6, 10, 4, 10, 28, 8 };
    Integer[] output = 
      MyHelperClass.mapObjectArray(array, value -> value * 2, Integer.class);

    assertThat(output).containsExactly(multipliedExpectedArray);
}

@Test
public void whenMapDividingObjectArray_thenReturnMultipliedArray() {
    Double[] multipliedExpectedArray = new Double[] { 1.5, 2.5, 1.0, 2.5, 7.0, 2.0 };
    Double[] output =
      MyHelperClass.mapObjectArray(array, value -> value / 2.0, Double.class);

    assertThat(output).containsExactly(multipliedExpectedArray);
}

Для примитивных типов, мы должны боксировать наши значения в первую очередь.

В качестве альтернативы мы можем обратиться к Потоки Java 8 для выполнения отображения для нас.

Нам нужно превратить массив в Поток Объект s в первую очередь. Мы можем сделать это с Arrays.stream метод.

Например, если мы хотим составить карту наших int значения пользовательского Струнные представительство, мы будем осуществлять это:

String[] stringArray = Arrays.stream(array)
  .mapToObj(value -> String.format("Value: %s", value))
  .toArray(String[]::new);

Создание массива

В Java создать массив можно с помощью оператора new с помощью следующего синтаксиса:

Вышеуказанное объявление делает две вещи:

  • Создает массив, используя new dataType;
  • Ссылка на недавно созданный массив присваивается переменной arrayRefVar.

Объявление переменной, создание и присвоение переменной ссылки массива могут быть объединены в одном операторе, как показано ниже:

В качестве альтернативы массивы в Java можно создавать следующим образом:

Элементы массива доступны через индекс. Отсчет индексов ведется от 0; то есть они начинают от 0 и до arrayRefVar.length-1.

Пример

Следующий оператор объявляет массив переменных myList, создает массив из 10 элементов типа double и присваивает ссылку myList:

Изображение отображает массив myList. Здесь myList имеет десять значений double и индексы от 0 до 9.

Интерфейс NavigableMap

Интерфейс NavigableMap был добавлен в Java 6. Она расширяет SortedМap и определяет поведение карты, поддерживающей извлечение элементов на основе ближайшего соответствия заданному ключу или ключам.

Методы интерфейса NavigableMap:

Методы позволяют получить соответственно меньший, меньше или равный, больший, больше или равную пару “ключ-значение” по отношению к заданному:

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

Методы pollFirstEntry и pollLastEntry возвращают соответственно первый и последний элементы карты, удаляя их из коллекции. Методы firstEntry и lastEntry также возвращают соответствующие элементы, но без удаления:

Возвращает карту, отсортированную в обратном порядке:

Методы, позволяющие получить набор ключей, отсортированных в прямом и обратном порядке соответственно:

Методы, позволяющие извлечь из карты подмножество. Как и в случае NavigableSet, указываем в параметрах начальный и конечный элементы массива ключей, а также необходимость включения в выходной набор граничных элементов. Опять же, если не указывать флаги, то будет использован интервал ключевых значений со включённым начальным элементом, но с исключённым конечным элементом:

Рассмотрение списка ArrayList

4.1. Использование ArrayList вместо массива

Часто проще использовать общий ArrayList вместо универсального массива. Давайте посмотрим, как мы можем изменить Мой стек для использования ArrayList .

Во-первых, давайте создадим поле для хранения наших элементов:

private List elements;

Во-вторых, в нашем конструкторе стека мы можем инициализировать ArrayList с начальной емкостью:

elements = new ArrayList<>(capacity);

Это упрощает наш класс, так как нам не нужно использовать отражение. Кроме того, нам не требуется передавать литерал класса при создании нашего стека. Наконец, поскольку мы можем установить начальную емкость ArrayList , мы можем получить те же преимущества, что и массив.

Поэтому нам нужно создавать массивы универсальных файлов только в редких ситуациях или когда мы взаимодействуем с какой-либо внешней библиотекой, для которой требуется массив.

4.2. Реализация ArrayList

Интересно, что ArrayList сам по себе реализован с использованием универсальных массивов. Давайте заглянем внутрь ArrayList , чтобы посмотреть, как это сделать.

Во-первых, давайте посмотрим поле элементы списка:

transient Object[] elementData;

Обратите внимание, что ArrayList использует Объект в качестве типа элемента. Поскольку наш универсальный тип неизвестен до времени выполнения, Объект используется в качестве суперкласса любого типа

Стоит отметить, что почти все операции в ArrayList может использовать этот универсальный массив, так как им не нужно предоставлять строго типизированный массив внешнему миру, за исключением одного метода – toArray !

Что такое отображение?

Отображение (или карта) представляет собой объект, сохраняющий связи между ключами и значениями в виде пар «ключ-значение». По заданному ключу можно найти его значение.

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

В одних отображениях допускаются null ключи и null значения, а в других — они не допускаются.

Уникальность ключей определяет реализация метода equals().

Для корректной работы с картами необходимо переопределить методы equals() и hashCode(). Допускается добавление объектов без переопределения этих методов, но найти эти объекты в Map вы не сможете.

1.1 Понятие массива

Массив – это совокупность элементов одного
типа, имеющих одно имя и расположенных в памяти ПК вплотную друг к другу.
Массивы могут состоять из арифметических данных, символов, строк, структур,
указателей. Доступ к отдельным элементам массива осуществляется по имени
массива и индексу (порядковому номеру) элемента.

При объявлении массива в программе
определяется имя массива, тип его элементов, размерность
и размер. Размерность или количество измерений
массива определяется количеством индексов при обращении к элементам массива.
Массивы бывают одномерные, двухмерные, трехмерные и т.д. . Размер массива
– это количество его элементов по соответствующим размерностям. Общий вид
объявления массива:

<имя_типа> <имя_массива>
… ;

где k1, k2, …, kn
количество элементов массива – константы или константные выражения по 1, 2,
…, n
измерениям. Причем значения индексов могут изменяться от
до ki – 1.

Такое объявление массива называют статическим,
поскольку предельное количество его элементов известно заранее и оно уже не
может быть изменено в ходе выполнения программы. При работе с массивами необходимо
следовать следующим правилам:

¨  
современные
трансляторы языка Си не контролируют допустимость значений индексов, это должен
делать программист;

¨  
количество измерений
массива не ограничено;

¨  
в памяти элементы
массива располагаются так, что при переходе от элемента к элементу наиболее
быстро меняется самый правый индекс массива, т.е. матрица, например,
располагается в памяти по строкам;

¨  
имя массива
является указателем – константой на первый элемент массива;

¨  
операций над
массивами в Си нет, поэтому пересылка элементов одного массива в другой может
быть реализована только поэлементно с помощью цикла;

¨  
над элементами
массива допускаются те же операции что и над простыми переменными того же типа;

¨  
ввод/вывод
значений элементов массива можно производить только поэлементно;

¨  
начальные
значения элементам массива можно присвоить при объявлении массива.

Примеры объявления массивов:

int   A ;     //одномерный массив
из 10 целочисленных величин

float   X ;     //одномерный
массив из 20 вещественных величин

int  a={1, 2, 3, 4, 5};   
//массив с инициализацией его элементов

int  c[]={–1 , 2, 0, –4, 5, –3, –5, –6,
1}; // массив размерность которого 6определяется числом инициализирующих
элементов

Обращения к элементам одномерного
массива могут иметь вид: A, A, A,…A, A.

В Си нет массивов с переменными
границами. Но, если количество элементов массива известно до выполнения
программы, можно определить его как константу с помощью директивы  #define,
а затем использовать ее в качестве границы массива, например,   

#define  n  10;

Main  ( )

{ int a, b;     // Объявление
2–х одномерных массивов

Если количество элементов массива
определяется в процессе выполнения программы, используют динамическое
выделение оперативной памяти компьютера.

Что такое массивы в Java?

Переменная — это место в нашей программе с именем и значением. Это значение может быть любым типом данных, например int. Массив другая переменная типа или объект — контейнер с фиксированным количеством значений, которые все из одного типа. Другими словами, набор схожих типов данных. При создании массива этот размер (или длина) также фиксируется.

Упрощенно: представьте массив Java как коробку с множеством отсеков, внутри каждого отсека находится одно значение.

Массив из 5 элементов с индексом начиная с 0

Отделения в коробке должны оставаться в порядке индексации. Элементы массива индексируются, и каждый индекс должен указывать на элемент. Это будет выглядеть примерно так:

У каждого отсека есть числовой индекс, который мы используем для доступа к значению. Индекс массива всегда начинается с 0. Допустим, у нас есть 10 отсеков в коробке контейнера массива. Будет 10 индексов, но они начинаются с 0 и заканчиваются 9, потому что индекс 0 указывает на первый элемент 1.

Что уникального в массивах в Java?

Массивы на каждом языке будут немного отличаться. Вот уникальные качества массивов в Java, которые отличаются от других языков, которые вы можете использовать, например C или C ++.

  • Массивы распределяются динамически
  • Массивы — это объекты в Java
  • Переменная массива Java объявляется так же, как и другие переменные.
  • Переменные упорядочены, индекс начинается с 0.
  • Суперкласс типа массива — это Object
  • Размер массива указывается с помощью int value

Массивы в Java — объявление и инициализация массива Java

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

int[] intArray;
float[] floatArray; 
char[] charArray;

Приведённые выше операторы объявления сообщают компилятору, что intArrayvariable – это массив целых чисел, floatArrayis – массив чисел с плавающей запятой, а charArrayis – массив символов.

Как и другие переменные, их нельзя использовать до инициализации и установки значения. В случае с массивом указание значения должно определять размер массива:

intArray = new int;

Число внутри скобок указывает, сколько элементов содержится в массиве. Приведённый выше код создает массив целых чисел, состоящий из 10 элементов.

Объявление и установку размера массива можно сделать в одном выражении:

float[] floatArray = new float;

Массивы не ограничиваются примитивными типами данных. Также можно создавать массив объектов Java (или строк):

String[] names = new String;

Синтаксис

let new_array = arr.map(function callback( currentValue[, index[, array]]) {
    // Возвращает элемент для new_array
}[, thisArg])

Функция, вызываемая для каждого элемента массива . Каждый раз, когда выполняется, возвращаемое значение добавляется в .

Функция , создающая элемент в новом массиве, принимает три аргумента:

Текущий обрабатываемый элемент массива.
Необязательный
Индекс текущего обрабатываемого элемента в массиве.
Необязательный
Массив, по которому осуществляется проход.
Необязательный
Необязательный параметр. Значение, используемое в качестве при вызове функции

Новый массив, где каждый элемент является результатом  функции.

Доступ и изменение элементов массива

Мы получаем доступ к элементу массива, используя его порядковый номер. Как мы обсуждали ранее, индекс начинается с 0 и заканчивается общим размером массива минус один. Если вы хотите получить доступ ко всем элементам массива, вы можете использовать forLoop.

Ниже приведен синтаксис доступа к элементам массива:

Продолжим наш предыдущий dogsпример. Ниже мы хотим получить доступ к первому значению и распечатать результат.

Примечание. В Java вы можете использовать System.out.printlnдля печати значения.

Мы также можем изменить значение элемента, используя его порядковый номер. Используя наш пример выше, скажем, мы хотим перейти Pitbullна Terrier.

Как получить элементы

Чтобы получить определенный элемент вы вызываете его метод get(), передавая ключ для этого элемента в качестве параметра:

String element1 =(String) mapA.get("key1");

Обратите внимание, что метод get() возвращает Java-объект, поэтому мы должны привести его к String(поскольку мы знаем, что значение является String). Позже в этом руководстве по Java Map вы увидите, как использовать Java Generics для ввода Map, чтобы она знала, какие конкретные типы ключей и значений она содержит

Это делает ненужным приведение типов и усложняет случайное добавление неправильных значений в карту.

Перебор ключей

Существует несколько способов итерации ключей, хранящихся на карте. Наиболее часто используемые методы:

  • С помощью ключа Iterator.
  • Через цикл for-each.
  • Через поток.

Все методы будут рассмотрены в следующих разделах.

Использование ключевого итератора

С помощью метода keySet():

Iterator iterator = mapA.keySet().iterator();
while(iterator.hasNext(){
  Object key   = iterator.next();
  Object value = mapA.get(key);
}

Как вы можете видеть, ключ Iterator возвращает каждый ключ, сохраненный в Map, один за другим (по одному для каждого вызова next()). Получив ключ, вы можете получить элемент, сохраненный для этого ключа, с помощью метода get().

Использование цикл for-each

В Java 5 вы также можете использовать цикл for-each для итерации ключей, хранящихся на карте:

for(Object key : mapA.keySet()) {
    Object value = mapA.get(key);
}

Эффект приведенного выше кода очень похож на код, показанный в предыдущем разделе.

Использование ключевого потока

Интерфейс Stream является частью Java Stream API, который был добавлен в Java 8. Сначала вы получаете ключ Set из карты, и из него вы можете получить Stream:

Map map = new HashMap<>();

map.put("one", "first");
map.put("two", "second");
map.put("three", "third");

Stream stream = map.keySet().stream();
stream.forEach((value) -> {
    System.out.println(value);
});    

Как создать массив в Java

При объявлении массива создается только ссылка на массив. Чтобы фактически создать или предоставить память массиву, надо создать массив следующим образом: общая форма new применительно к одномерным и выглядит следующим образом:

Здесь type указывает тип данных, size – количество элементов в массиве, а var-name-имя переменной массива.

Пример:

int intArray[];    //объявление
intArray = new int;  // выделение памяти 

или

int[] intArray = new int; // объединение

Литералы массива

В ситуации, когда размер массива и переменные уже известны, можно использовать литералы.

int[] intArray = new int[]{ 1,2,3,4,5,6,7,8,9,10 }; 
 // Declaring array literal
  • Длина этого массива определяет длину созданного массива.
  • Нет необходимости писать int[] в последних версиях Java

Доступ к элементам массива Java с помощью цикла for

Доступ к каждому элементу массива осуществляется через его индекс. Индекс начинается с 0 и заканчивается на (общий размер)-1. Все элементы могут быть доступны с помощью цикла for.

// accessing the elements of the specified array
for (int i = 0; i < arr.length; i++)
  System.out.println("Element at index " + i + 
                                " : "+ arr);

// Пример для иллюстрации создания array // целых чисел, помещает некоторые значения в массив, // и выводит каждое значение.

class GFG { public static void main (String[] args) { // declares an Array of integers. int[] arr;

// allocating memory for 5 integers. arr = new int;

// initialize the first elements of the array arr = 10;

// initialize the second elements of the array arr = 20;

//so on… arr = 30; arr = 40; arr = 50;

// accessing the elements of the specified array for (int i = 0; i < arr.length; i++) System.out.println(“Element at index ” + i + ” : “+ arr); } } В итоге получаем:

Element at index 0 : 10
Element at index 1 : 20
Element at index 2 : 30
Element at index 3 : 40
Element at index 4 : 50

Для сортировки — sorted()

Этот метод используется для сортировки элементов стрима. По умолчанию применяется сортировка по возрастанию (с числами всё понятно, а вот заглавные и строчные буквы рассматриваются отдельно).

Примечание. Метод подходит только для сортировки объектов, которые реализуют интерфейс Comparable.

Если же классы наших объектов не реализуют этот интерфейс или нужна иная логика сортировки, то можно передать в качестве аргумента свой алгоритм сравнения элементов.

В результате работы метода получается новый стрим.

Без лямбд

У интерфейса List есть метод для сортировки — sort(). В него тоже можно передать алгоритм сравнения. До появления лямбд для этого создавали свои классы, реализующие интерфейс Comparator, или анонимные классы:

Метод sort() не возвращает результат, он преобразует исходную коллекцию. Поэтому в нашем примере пришлось вынести сортировку в отдельный метод, чтобы не менять текущий порядок книг.

С лямбдами

Для передачи алгоритма сравнения элементов в метод sorted() используется лямбда-выражение Comparator.comparing(Book: :getIssueYear).

Оно равносильно анонимному классу в примере выше: означает, что книги сравниваются по году издания.

Метод collect(Collectors.toList()) замыкает стрим в список (List).

Создавать отдельный метод для сортировки не пришлось. И в целом код выглядит компактнее.

Как распечатать массив

То же, что и с равняется метод, набор массива toString функция использует реализацию по умолчанию, предоставляемую Объект класс, который не очень полезен.

Оба Массивы и ArrayUtils классы отправки с их реализации для преобразования структур данных в читаемый Струнные .

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

Класс Java Util предоставляет два статических метода, которые мы можем использовать:

  • toString : не работает хорошо с зубчатыми массивами
  • deepToString : поддерживает любую Объект на основе массивов, но не компилирует с примитивными аргументами массива

С другой стороны, Реализация Apache предлагает единый toString метод, который работает правильно в любом случае:

String arrayAsString = ArrayUtils.toString(array);

Описание

Метод вызывает переданную функцию один раз для каждого элемента, в порядке их появления и конструирует новый массив из результатов её вызова. Функция вызывается только для индексов массива, имеющих присвоенные значения, включая . Она не вызывается для пропущенных элементов массива (то есть для индексов, которые никогда не были заданы, которые были удалены или которым никогда не было присвоено значение.

Функция вызывается с тремя аргументами: значением элемента, индексом элемента и массивом, по которому осуществляется проход.

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

Метод не изменяет массив, для которого он был вызван (хотя функция может это делать).

Диапазон элементов, обрабатываемых методом , устанавливается до первого вызова функции . Элементы, добавленные в массив после начала выполнения метода , не будут посещены функцией . Если существующие элементы массива изменяются функцией , их значения, переданные в функцию, будут значениями на тот момент времени, когда метод посетит их; удалённые элементы посещены не будут.

Рейтинг
( Пока оценок нет )
Понравилась статья? Поделиться с друзьями:
Все про сервера
Добавить комментарий

;-) :| :x :twisted: :smile: :shock: :sad: :roll: :razz: :oops: :o :mrgreen: :lol: :idea: :grin: :evil: :cry: :cool: :arrow: :???: :?: :!: