diff --git a/modules/35-methods-using/100-methods/en/EXERCISE.md b/modules/35-methods-using/100-methods/en/EXERCISE.md new file mode 100644 index 00000000..0dbd2fa8 --- /dev/null +++ b/modules/35-methods-using/100-methods/en/EXERCISE.md @@ -0,0 +1,2 @@ + +In the program code, two variables are defined that contain company names. Calculate their total length in characters and print it to the screen. diff --git a/modules/35-methods-using/100-methods/en/README.md b/modules/35-methods-using/100-methods/en/README.md new file mode 100644 index 00000000..a9c8bcff --- /dev/null +++ b/modules/35-methods-using/100-methods/en/README.md @@ -0,0 +1,116 @@ +Programming exists to perform all kinds of operations. Sometimes these are simple actions, such as adding numbers or joining strings. But more often they are complex processes, like transferring money from one account to another, placing an order in an online store, calculating taxes, or preparing a report. + +Such operations cannot be expressed with a single command. Behind an action like "transfer money" hide dozens, hundreds, and even thousands of lines of code. This includes checking the balance, deducting the amount, accounting for the fee, updating the database, and sending a notification to the user. + +To manage this code and not get lost in the details, programming came up with a special mechanism. It combines a block of code into a single whole, hides the implementation, and lets you focus on the meaning. For the programmer, it is enough to call it and entrust all the internal work to it. + +## How operations are expressed + +To express an arbitrary operation, most programming languages use **functions**. A function combines a block of code under a single name. From the outside, everything looks like one command, while the hundreds of lines inside remain hidden. + +Here we need to make a caveat. In Java, you cannot create an ordinary function, as most other languages allow. All functions in Java are created only inside classes, which we have not covered yet. Functions defined inside classes are commonly called **methods**. From now on, we will stick to this terminology. + +We are already familiar with one method — `println()`. It prints data to the screen. Methods are one of the key constructs in programming; without them, you can hardly do anything. First, we will learn how to use ready-made methods, and only then create our own. + +Let's start with methods for working with strings. Below is a call to the `length()` method, which counts the number of characters in a string: + +```java +"Hexlet".length(); // 6 +"ABBA".length(); // 4 +``` + +The first string has six characters, so `"Hexlet".length()` returns `6`. The second string has four characters, and the result is `4`. + +**Methods** are actions that are performed on data. In programming, **objects** are data that have methods. In reality, everything is a bit more complicated, but for now this definition is enough. In Java, all non-primitive (reference) data types are objects, and strings are among them. + +Let's look at the structure of a call. First comes the object itself, then a dot, then the **name** of the method and round **parentheses**. The dot shows that the method is called on a specific object. The parentheses show that this is exactly a call, and not an access to data. + +Inside the parentheses go the **arguments**, that is, the data that the method receives to work with. There can be several of them, one, or none at all. The `length()` method has no arguments, so the parentheses are empty. + +## Where methods come from + +Some methods are built into the language, others are created by programmers themselves. + +**Built-in methods** come together with Java. You can use them right away, without any additional actions. An example of such a method is `length()` on a string. A large number of methods are available on strings, numbers, and other data types right out of the box. + +**Methods that programmers create** appear when you need to package your own logic into a separate block. Such a method can be given any name and called the same way as a built-in one. We will learn this later. + +In addition, there are methods from external libraries. To use them, the library is connected using the import mechanism. We are not covering imports in detail yet. It is enough to know that it adds a set of ready-made methods to the program. + +## A method without arguments + +One of the frequently used string methods is `length()`. For a string, it returns the number of characters. + +```java +var message = "Hello!"; +var count = message.length(); +System.out.println(count); // => 6 +``` + +Here the string `"Hello!"` has six characters, so the call `message.length()` returns the number `6`. + +```text +Object Method Result +┌──────────┐ ┌──────────┐ ┌──────────┐ +│ "Hello!" │ ──→ │ length() │ ──→ │ 6 │ +└──────────┘ └──────────┘ └──────────┘ +``` + +## Returning a value + +Returning a value is one of the key principles of how methods work. Thanks to it, we connect the results of different actions and build more complex logic. If a method returns a value, it can be saved in a variable, passed to another method, or used in calculations. This is exactly how `length()` works. It counts the number of characters and gives the result back out. + +```java +var message1 = "Hello!"; +var length1 = message1.length(); // save the result + +var message2 = "World!"; +var length2 = message2.length(); + +// use the result in an expression +var combinedLength = length1 + length2; +System.out.println(combinedLength); // 12 +``` + +Methods almost never print data to the screen, they return it. If `length()` printed the result right away, the way `println()` does, we would see the number but could not use it further. That is why returning a value is so important. It links methods together. Some return data, others use it in their work. This is exactly how big and complex programs are built from small steps. + +In the examples above, the result of each call is written into a variable. But this is not required; a method can be used directly: + +```java +var message = "Hexlet"; +System.out.println(message.length()); // => 6 +``` + +## A method with arguments + +Some methods accept several pieces of data to work with at once. An example is the static method `Math.max()`, which returns the larger of two numbers. The first argument sets one number, the second sets the other. + +```java +// Choose the larger of 2 and 3 +var result = Math.max(2, 3); +System.out.println(result); // => 3 + +// Choose the larger of 10 and 7 +System.out.println(Math.max(10, 7)); // => 10 +``` + +Here the method is called not on a string, but on the `Math` class through a dot. Such methods are called **static**; they belong to the class itself. In terms of structure, a call with several arguments is no different from a call without them. The same method name, parentheses, and arguments separated by commas inside. + +## Parameters and arguments + +In discussions about methods, the words **parameters** and **arguments** come up again and again. They are related to each other, but they mean different things. + +**Parameters** are talked about when creating a method. A parameter is a variable inside the method into which the passed value goes. **Arguments** are talked about when calling. An argument is what we pass into the method. It is a number, a variable, or any expression. + +```java +// numbers as arguments +System.out.println(Math.max(2, 3)); // => 3 + +var x = 2; +// an argument can be an expression, it is evaluated before being passed to the method +System.out.println(Math.max(x + 1, 3)); // => 3 +``` + +You do not have to memorize this, but it will be useful when reading English-language literature. + +Gradually, we will get to know more and more built-in methods. There are so many of these methods that it is impossible to remember them all. The good news is that this is not required. No one remembers method names by heart. The main thing is to have a rough idea of what you need, and then the editor's hints, the documentation, and search will help. Programmers constantly sit in the documentation, figuring out how everything works. diff --git a/modules/35-methods-using/100-methods/en/data.yml b/modules/35-methods-using/100-methods/en/data.yml new file mode 100644 index 00000000..e98f0ef4 --- /dev/null +++ b/modules/35-methods-using/100-methods/en/data.yml @@ -0,0 +1,13 @@ +--- +name: Methods and their call +tips: [] +definitions: + - name: Method + description: >- + an operation that belongs to an object or a class and is able to accept + data and return a result. A method is called through a dot, for example + `"Hexlet".length()`. + - name: Argument + description: >- + the information that a method receives when it is called. For example, + `Math.max(2, 3)` passes the arguments `2` and `3` to the `max()` method. diff --git a/modules/35-methods-using/100-methods/es/EXERCISE.md b/modules/35-methods-using/100-methods/es/EXERCISE.md index 29b5a691..43be8644 100644 --- a/modules/35-methods-using/100-methods/es/EXERCISE.md +++ b/modules/35-methods-using/100-methods/es/EXERCISE.md @@ -1,2 +1,2 @@ -En el código del programa se han definido dos variables que contienen nombres de empresas. Calcule la longitud total de los nombres en caracteres y muéstrela en pantalla. +En el código del programa se han definido dos variables que contienen nombres de empresas. Calcule su longitud total en caracteres y muéstrela en pantalla. diff --git a/modules/35-methods-using/100-methods/es/README.md b/modules/35-methods-using/100-methods/es/README.md index 4202c738..20bbabc4 100644 --- a/modules/35-methods-using/100-methods/es/README.md +++ b/modules/35-methods-using/100-methods/es/README.md @@ -1,45 +1,116 @@ -La suma, la concatenación, el cálculo del resto de la división y otras operaciones previamente discutidas son capacidades bastante básicas de los lenguajes de programación. +La programación existe para realizar operaciones muy diversas. A veces son acciones simples, como sumar números o unir cadenas de texto. Pero más a menudo son procesos complejos, como transferir dinero de una cuenta a otra, tramitar un pedido en una tienda en línea, calcular impuestos o preparar un informe. -Las matemáticas no se limitan a la aritmética, también hay muchas otras ramas con sus propias operaciones, como la geometría. Lo mismo ocurre con las cadenas de texto: se pueden invertir, cambiar el caso de las letras, eliminar caracteres innecesarios, y eso es solo lo más básico. A un nivel más alto, existe la lógica aplicada a una aplicación específica. +Estas operaciones no se pueden expresar con una sola instrucción. Detrás de una acción como "transferir dinero" se ocultan decenas, cientos e incluso miles de líneas de código. Esto incluye comprobar el saldo, descontar la cantidad, tener en cuenta la comisión, actualizar la base de datos y enviar una notificación al usuario. -Los programas realizan transacciones monetarias, calculan impuestos, generan informes. La cantidad de operaciones similares es infinita y es única para cada programa. Y todas ellas deben ser expresadas de alguna manera en el código. +Para gestionar este código y no perderse en los detalles, en la programación se ideó un mecanismo especial. Reúne un bloque de código en un todo único, oculta la implementación y permite centrarse en el sentido. Al programador le basta con llamarlo y confiarle todo el trabajo interno. ## Cómo se expresan las operaciones -Para expresar cualquier operación arbitraria en programación, existe el concepto de **función**. Las funciones pueden ser tanto incorporadas en el lenguaje como agregadas por el programador. Ya estamos familiarizados con una función incorporada: `println()`. +Para expresar una operación arbitraria, la mayoría de los lenguajes de programación utilizan **funciones**. Una función reúne un bloque de código bajo un solo nombre. Desde fuera, todo parece una sola instrucción, mientras que los cientos de líneas de su interior permanecen ocultas. -Las funciones son una de las construcciones clave en programación, sin ellas no se puede hacer prácticamente nada. Primero aprenderemos a utilizar las funciones ya creadas y luego aprenderemos a crear nuestras propias funciones. +Aquí hay que hacer una aclaración. En Java no es posible crear una función común, como lo permiten la mayoría de los otros lenguajes. Todas las funciones en Java se crean solo dentro de clases, que aún no hemos estudiado. Las funciones definidas dentro de clases se suelen llamar **métodos**. En adelante nos atendremos a esta terminología. -Aquí es necesario hacer una pequeña aclaración. En Java no es posible crear una función común, como lo permiten la mayoría de los otros lenguajes. Todas las funciones en Java se crean solo dentro de clases, que aún no hemos estudiado. Y las funciones que están definidas dentro de las clases se llaman **métodos**. Por lo tanto, en el futuro nos adheriremos a esta terminología. +Ya conocemos un método: `println()`. Muestra datos en la pantalla. Los métodos son una de las construcciones clave en la programación, sin ellos no se puede hacer casi nada. Primero aprenderemos a usar métodos ya creados y solo después a crear los nuestros propios. -Comenzaremos con métodos simples para trabajar con cadenas de texto. A continuación se muestra un ejemplo de llamada al método `length()`, que cuenta la cantidad de caracteres en una cadena: +Empecemos con los métodos para trabajar con cadenas de texto. A continuación se muestra una llamada al método `length()`, que cuenta la cantidad de caracteres en una cadena: ```java "Hexlet".length(); // 6 -"ABBA".length(); // 4 +"ABBA".length(); // 4 ``` -Los **métodos** son acciones que se deben realizar sobre los datos a los que se aplican. En programación, los **objetos** son los datos que tienen métodos. En realidad, es un poco más complicado, pero por ahora esta definición es suficiente. En Java, todos los tipos de datos no primitivos (de referencia) son objetos. Veamos algunos ejemplos más con la adición de variables: +La primera cadena tiene seis caracteres, por eso `"Hexlet".length()` devuelve `6`. La segunda cadena tiene cuatro caracteres, y el resultado es `4`. + +Los **métodos** son acciones que se realizan sobre los datos. En programación, se llama **objetos** a los datos que tienen métodos. En realidad todo es un poco más complicado, pero por ahora esta definición es suficiente. En Java, todos los tipos de datos no primitivos (de referencia) son objetos, y las cadenas están entre ellos. + +Veamos la estructura de una llamada. Primero se escribe el propio objeto, luego un punto, después el **nombre** del método y los **paréntesis**. El punto muestra que el método se llama sobre un objeto concreto. Los paréntesis muestran que se trata precisamente de una llamada, y no de un acceso a los datos. + +Dentro de los paréntesis se indican los **argumentos**, es decir, los datos que el método recibe para trabajar. Puede haber varios, uno o ninguno. El método `length()` no tiene argumentos, por eso los paréntesis están vacíos. + +## De dónde vienen los métodos + +Algunos métodos están incorporados en el lenguaje, otros los crean los propios programadores. + +Los **métodos incorporados** vienen junto con Java. Se pueden usar de inmediato, sin acciones adicionales. Un ejemplo de tal método es `length()` en una cadena. Una gran cantidad de métodos está disponible en las cadenas, los números y otros tipos de datos directamente, de fábrica. + +Los **métodos que crean los programadores** aparecen cuando hace falta organizar la propia lógica en un bloque aparte. A tal método se le puede dar cualquier nombre y llamarlo igual que a uno incorporado. Aprenderemos esto más adelante. + +Además, existen métodos de bibliotecas externas. Para usarlos, la biblioteca se conecta mediante el mecanismo de importación. Por ahora no estudiamos la importación en detalle. Basta con saber que añade al programa un conjunto de métodos ya listos. + +## Un método sin argumentos + +Uno de los métodos de cadena más usados es `length()`. Para una cadena, devuelve la cantidad de caracteres. + +```java +var message = "Hello!"; +var count = message.length(); +System.out.println(count); // => 6 +``` + +Aquí la cadena `"Hello!"` tiene seis caracteres, por eso la llamada `message.length()` devuelve el número `6`. + +```text +Objeto Método Resultado +┌──────────┐ ┌──────────┐ ┌──────────┐ +│ "Hello!" │ ──→ │ length() │ ──→ │ 6 │ +└──────────┘ └──────────┘ └──────────┘ +``` + +## Devolución de un valor + +La devolución de un valor es uno de los principios clave del funcionamiento de los métodos. Gracias a ella, unimos los resultados de distintas acciones y construimos una lógica más compleja. Si un método devuelve un valor, se puede guardar en una variable, pasar a otro método o usar en cálculos. Así funciona exactamente `length()`. Cuenta la cantidad de caracteres y entrega el resultado hacia fuera. + +```java +var message1 = "Hello!"; +var length1 = message1.length(); // guardamos el resultado + +var message2 = "World!"; +var length2 = message2.length(); + +// usamos el resultado en una expresión +var combinedLength = length1 + length2; +System.out.println(combinedLength); // 12 +``` + +Los métodos casi nunca muestran datos en la pantalla, los devuelven. Si `length()` imprimiera el resultado de inmediato, como hace `println()`, veríamos el número, pero no podríamos usarlo después. Por eso la devolución de un valor es tan importante. Enlaza los métodos entre sí. Unos devuelven datos, otros los usan en su trabajo. Así es exactamente como, a partir de pequeños pasos, se construyen programas grandes y complejos. + +En los ejemplos anteriores, el resultado de cada llamada se escribe en una variable. Pero esto no es obligatorio, un método se puede usar directamente: ```java -var company = "Hexlet"; +var message = "Hexlet"; +System.out.println(message.length()); // => 6 +``` + +## Un método con argumentos + +Algunos métodos aceptan varios datos a la vez para trabajar. Un ejemplo es el método estático `Math.max()`, que devuelve el mayor de dos números. El primer argumento indica un número, el segundo indica el otro. -var companyLength = company.length(); -System.out.println(companyLength); // => 6 +```java +// Elegimos el mayor de 2 y 3 +var result = Math.max(2, 3); +System.out.println(result); // => 3 -// Convertir a mayúsculas -company.toUpperCase(); // "HEXLET" +// Elegimos el mayor de 10 y 7 +System.out.println(Math.max(10, 7)); // => 10 ``` -Lo más importante en el trabajo con métodos es comprender el concepto de retorno de valor. Los métodos casi nunca muestran datos en la pantalla, sino que los devuelven. Gracias a esta propiedad, podemos dividir nuestro programa en fragmentos que luego se combinan en algo más complejo. +Aquí el método se llama no sobre una cadena, sino sobre la clase `Math` a través de un punto. Estos métodos se llaman **estáticos**, pertenecen a la propia clase. En cuanto a la estructura, una llamada con varios argumentos no se diferencia de una llamada sin ellos. El mismo nombre del método, los paréntesis y los argumentos separados por comas dentro. + +## Parámetros y argumentos -En los ejemplos anteriores, el resultado de llamar a cada método se guarda en variables. Pero esto no es obligatorio, podemos usar los métodos directamente: +En las conversaciones sobre los métodos aparecen una y otra vez las palabras **parámetros** y **argumentos**. Están relacionadas entre sí, pero designan cosas diferentes. + +De los **parámetros** se habla al crear un método. Se llama parámetro a la variable dentro del método en la que cae el valor pasado. De los **argumentos** se habla al llamar. Se llama argumento a lo que pasamos al método. Es un número, una variable o cualquier expresión. ```java -var company = "Hexlet"; -System.out.println(company.length()); // => 6 +// números como argumentos +System.out.println(Math.max(2, 3)); // => 3 + +var x = 2; +// un argumento puede ser una expresión, se evalúa antes de pasarlo al método +System.out.println(Math.max(x + 1, 3)); // => 3 ``` -Gradualmente nos familiarizaremos con cada vez más métodos incorporados en el lenguaje. Hay tantos métodos que es imposible recordarlos todos. La buena noticia es que no es necesario. Nadie recuerda los nombres de los métodos de memoria. +No es obligatorio memorizar esto, pero será útil al leer literatura en inglés. -Lo más importante es tener una idea aproximada de lo que se necesita, y luego se pueden utilizar las sugerencias del editor, la documentación y Google. Los programadores pasan mucho tiempo en la documentación, tratando de entender cómo funciona todo. +Poco a poco iremos conociendo cada vez más métodos incorporados. Estos métodos son tan numerosos que es imposible recordarlos. La buena noticia es que tampoco hace falta. Nadie recuerda de memoria los nombres de los métodos. Lo principal es tener una idea aproximada de lo que se necesita, y luego ayudarán las sugerencias del editor, la documentación y las búsquedas. Los programadores pasan constantemente tiempo en la documentación, tratando de entender cómo funciona cada cosa. diff --git a/modules/35-methods-using/100-methods/es/data.yml b/modules/35-methods-using/100-methods/es/data.yml index cb52acf7..4f9a8952 100644 --- a/modules/35-methods-using/100-methods/es/data.yml +++ b/modules/35-methods-using/100-methods/es/data.yml @@ -1,2 +1,13 @@ --- name: Métodos y su llamada +tips: [] +definitions: + - name: Método + description: >- + una operación que pertenece a un objeto o a una clase y es capaz de + recibir datos y devolver un resultado. Un método se llama a través de un + punto, por ejemplo `"Hexlet".length()`. + - name: Argumento + description: >- + la información que un método recibe al ser llamado. Por ejemplo, + `Math.max(2, 3)` pasa los argumentos `2` y `3` al método `max()`. diff --git a/modules/35-methods-using/105-methods-parameters/en/EXERCISE.md b/modules/35-methods-using/105-methods-parameters/en/EXERCISE.md new file mode 100644 index 00000000..f37f3b70 --- /dev/null +++ b/modules/35-methods-using/105-methods-parameters/en/EXERCISE.md @@ -0,0 +1,14 @@ + +You are given three variables with the surnames of different people. Compose and print to the screen a word made of characters in the following order: + +1. the third character from the first string; +2. the second character from the second string; +3. the fourth character from the third string; +4. the fifth character from the second string; +5. the third character from the second string. + +The output of the result should look approximately like this: + +```text +a b c d e +``` diff --git a/modules/35-methods-using/105-methods-parameters/en/README.md b/modules/35-methods-using/105-methods-parameters/en/README.md new file mode 100644 index 00000000..383cb984 --- /dev/null +++ b/modules/35-methods-using/105-methods-parameters/en/README.md @@ -0,0 +1,47 @@ + +The `length()` method does not require any clarifications. It always works unambiguously and extracts the full length of the string. + +But this is not always the case. For example, if we want to extract the first character from a string, we need to explicitly indicate that the character is the first one. To do this, we can pass parameters into method calls: + +```java +var searchEngine = "google"; +// Returns the first character (char type) +searchEngine.charAt(0); // 'g' +``` + +Why is the character the first one, but 0 is specified? In programming, counting starts from zero. That is why the first character is at position zero — "index 0". + +Accordingly, the last character has an index equal to the length of the string minus 1: + +```java +// google length => 6 +searchEngine.charAt(5); // 'e' +``` + +## Several parameters + +There can be more than one parameter. For example, the `replace()` method works with two, where the first is what to replace, and the second is what to replace it with: + +```java +searchEngine.replace("go", "mo"); // "moogle" +``` + +## Default values + +Parameters can contain a default value where that value is used most often. + +This capability was added to languages to relieve the programmer of routine work. A simple example is a method that extracts a substring from a string, that is, a part of the string. + +This method takes as input: + +* As the first parameter, the index from which to start extracting the substring +* As the second parameter, the index up to which to extract characters + +By default, the string is taken up to the end: + +```java +"hexlet".substring(1); // "exlet" +"hexlet".substring(1, 2); // "e" +"hexlet".substring(1, 3); // "ex" +"hexlet".substring(3, 6); // "let" +``` diff --git a/modules/35-methods-using/105-methods-parameters/en/data.yml b/modules/35-methods-using/105-methods-parameters/en/data.yml new file mode 100644 index 00000000..75c4ddc4 --- /dev/null +++ b/modules/35-methods-using/105-methods-parameters/en/data.yml @@ -0,0 +1,2 @@ +--- +name: Method parameters diff --git a/modules/35-methods-using/110-methods-as-expressions/en/EXERCISE.md b/modules/35-methods-using/110-methods-as-expressions/en/EXERCISE.md new file mode 100644 index 00000000..50a1ad35 --- /dev/null +++ b/modules/35-methods-using/110-methods-as-expressions/en/EXERCISE.md @@ -0,0 +1,9 @@ + +Print to the screen the first and last letters of the sentence stored in the `text` variable, in the following format: + +```text +First: N +Last: t +``` + +Try to create only one variable, into which the needed text is written right before printing to the screen. In this lesson, we practice the skill of assembling a compound expression. diff --git a/modules/35-methods-using/110-methods-as-expressions/en/README.md b/modules/35-methods-using/110-methods-as-expressions/en/README.md new file mode 100644 index 00000000..3a704e60 --- /dev/null +++ b/modules/35-methods-using/110-methods-as-expressions/en/README.md @@ -0,0 +1,124 @@ +When we write programs, we need to connect actions with one another. Adding numbers, joining strings, and working with variables are examples of how simple steps combine into more complex behavior. + +```java +var rate = 10; +var hours = 5; +var salary = rate * hours + 100; +System.out.println(salary); // => 150 +``` + +In programming, the concept of an **expression** is used for this. That is the name for a construct that is evaluated and gives a result. In the example above, `rate * hours + 100` is an expression. It is composed of variables (`rate`, `hours`), a numeric literal (`100`), and arithmetic operations. Together they return a result that can be saved in a variable or used further. + +The peculiarity of expressions is that their result can always be applied — assigned to a variable, passed to a method, or printed to the screen: + +```java +// Here the expression is 1 + 5 +var sum = 1 + 5; +System.out.println(1 + 5); +``` + +But not everything in programming is an expression. A variable declaration is a statement; it cannot be part of an expression. That is why the following code will produce an error: + +```java +// Meaningless code that will not work +10 + var sum = 1 + 5; +``` + +Expressions can be combined endlessly, gradually complicating the logic. Each new expression becomes part of a larger one: + +```java +var rate = 10; +var hours = 5; +var bonus = 50; +// An expression made of many operations +var salary = (rate * hours + bonus) * 12 - 500; +System.out.println(salary); +``` + +Here several expressions are combined into one, and the result has become even more complex. This is exactly how programs are built. Small steps add up into large constructs. That is why in programming it is impossible to memorize all combinations in advance. It is much more important to understand how expressions connect with each other into the desired result. + +## A method call as an expression + +Let's talk about methods. Is a method call an expression or not? We know that methods return a result, so yes, a method call is an expression. A lot of interesting things automatically follow from this. + +For example, we can use a method call directly in mathematical operations. Here is how to get the index of the last character in a word: + +```java +// Indexes start from zero +var name = "Java"; +// A method call and subtraction together +var lastIndex = name.length() - 1; +System.out.println(lastIndex); // => 3 +``` + +There is no new syntax in this code. We have merely connected already known parts, relying on their nature. The `length()` method returns the number `4`, we subtract one from it and get `3`. We can go even further and embed the call directly into the output: + +```java +System.out.println(name.length() - 1); // => 3 +``` + +## Expressions as method arguments + +A method argument is always some value. But a value can not only be written directly, it can also be computed. And that means any expressions can be substituted as arguments. + +```java +// Here the argument of println is the number 150 +System.out.println(150); + +// And here the argument is an expression that is evaluated first +System.out.println(10 * 15); // => 150 + +// You can combine it in an even more complex way +var rate = 10; +var hours = 15; +var bonus = 50; +System.out.println(rate * hours + bonus); // => 200 +``` + +The `println()` method receives a ready value and prints it to the screen. The way this value is obtained is indifferent to the method. That is why method calls combine perfectly with any expressions. + +## A method call inside a method + +Since a method call is itself an expression, its result can be passed directly to another method. This allows building even more complex constructs: + +```java +var name = "Java"; + +// The call name.length() returns 4 +// This result is immediately used as an argument of println() +System.out.println(name.length()); // => 4 +``` + +Here `name.length()` is evaluated first and returns the number `4`. Then this value is substituted into the `println()` call. To read such constructs correctly, you need to remember the order of evaluation. + +1. First, the method that is "inside" is executed, in our case `name.length()`. +2. Then its result is substituted in place of the call. +3. After that, the outer method is executed, in our case `println()`. + +The code `System.out.println(name.length())` can be mentally broken down like this: + +```text +System.out.println("Java".length()) + +Step 1: "Java".length() → 4 +Step 2: println(4) → prints 4 +``` + +This principle always works. First the nested calls are evaluated, then the outer one. + +## Methods as part of expressions + +Methods return values, so their calls can be used as part of any other expressions. This is true for all methods, including string ones: + +```java +var name = "Java"; +// toUpperCase() converts the word to uppercase +System.out.println("Hello " + name.toUpperCase()); // => Hello JAVA + +// You can use the result of a method in arithmetic +var text = "hexlet"; +var doubled = text.length() * 2; +System.out.println(doubled); // => 12 +``` + +Here the calls `name.toUpperCase()` and `text.length()` are full-fledged expressions. They return values that are combined with strings, numbers, variables, and other operations. diff --git a/modules/35-methods-using/110-methods-as-expressions/en/data.yml b/modules/35-methods-using/110-methods-as-expressions/en/data.yml new file mode 100644 index 00000000..6fff6c7a --- /dev/null +++ b/modules/35-methods-using/110-methods-as-expressions/en/data.yml @@ -0,0 +1,7 @@ +--- +name: A method call is an expression +definitions: + - name: Expression + description: >- + a sequence of actions on data that leads to a result, which can then be + used further. diff --git a/modules/35-methods-using/110-methods-as-expressions/es/EXERCISE.md b/modules/35-methods-using/110-methods-as-expressions/es/EXERCISE.md index ce27de03..295bf41a 100644 --- a/modules/35-methods-using/110-methods-as-expressions/es/EXERCISE.md +++ b/modules/35-methods-using/110-methods-as-expressions/es/EXERCISE.md @@ -1,9 +1,9 @@ -Muestra en pantalla la primera y la última letra de la oración que se encuentra en la variable `text`, en el siguiente formato: +Muestra en pantalla la primera y la última letra de la oración almacenada en la variable `text`, en el siguiente formato: ```text First: N Last: t ``` -Intenta crear solo una variable en la que se almacene el texto necesario antes de imprimirlo en pantalla. En esta lección, practicamos la habilidad de construir expresiones compuestas. +Intenta crear una sola variable en la que se escriba directamente el texto necesario antes de imprimirlo en pantalla. En esta lección practicamos la habilidad de construir una expresión compuesta. diff --git a/modules/35-methods-using/110-methods-as-expressions/es/README.md b/modules/35-methods-using/110-methods-as-expressions/es/README.md index 732ee8c8..fde7fe8d 100644 --- a/modules/35-methods-using/110-methods-as-expressions/es/README.md +++ b/modules/35-methods-using/110-methods-as-expressions/es/README.md @@ -1,15 +1,15 @@ -En programación, una expresión es algo que devuelve un resultado que se puede utilizar. - -Ya sabemos bastante sobre las expresiones y los principios de su construcción. La suma, la resta, la concatenación y otras operaciones matemáticas y de cadenas de texto son todas expresiones: +Cuando escribimos programas, necesitamos conectar unas acciones con otras. La suma de números, la unión de cadenas de texto y el trabajo con variables son ejemplos de cómo pasos simples se combinan en un comportamiento más complejo. ```java -1 + 5 * 3; -"He" + "Let"; -// Las variables pueden formar parte de una expresión -rate * 5; +var rate = 10; +var hours = 5; +var salary = rate * hours + 100; +System.out.println(salary); // => 150 ``` -La característica de las expresiones es que devuelven un resultado que se puede utilizar, como asignarlo a una variable o mostrarlo en pantalla: +En programación, para esto se usa el concepto de **expresión**. Así se llama a una construcción que se evalúa y da un resultado. En el ejemplo anterior, `rate * hours + 100` es una expresión. Está compuesta por variables (`rate`, `hours`), un literal numérico (`100`) y operaciones aritméticas. En conjunto, devuelve un resultado que se puede guardar en una variable o usar más adelante. + +La particularidad de las expresiones es que su resultado siempre se puede aplicar: asignarlo a una variable, pasarlo a un método o mostrarlo en pantalla: ```java // Aquí la expresión es 1 + 5 @@ -17,37 +17,108 @@ var sum = 1 + 5; System.out.println(1 + 5); ``` -Pero no todo en programación es una expresión. La declaración de una variable es una instrucción y no puede formar parte de una expresión. Es decir, este código dará un error: +Pero no todo en programación es una expresión. La declaración de una variable es una instrucción, no puede formar parte de una expresión. Por eso el siguiente código dará un error: ```java // Código sin sentido que no funcionará 10 + var sum = 1 + 5; ``` -Como verás más adelante, las expresiones se pueden combinar para obtener comportamientos más complejos en lugares inesperados y de formas inesperadas. Entenderás mejor cómo se pueden unir las partes del código para obtener el resultado deseado. +Las expresiones se pueden combinar infinitamente, complicando poco a poco la lógica. Cada nueva expresión se convierte en parte de una mayor: + +```java +var rate = 10; +var hours = 5; +var bonus = 50; +// Una expresión formada por muchas operaciones +var salary = (rate * hours + bonus) * 12 - 500; +System.out.println(salary); +``` + +Aquí varias expresiones se combinan en una sola, y el resultado se ha vuelto aún más complejo. Así es exactamente como se construyen los programas. Los pequeños pasos se suman en grandes construcciones. Por eso en programación es imposible aprender de antemano todas las combinaciones. Es mucho más importante entender cómo se conectan las expresiones entre sí para dar el resultado deseado. -Hablemos de los métodos. ¿Una llamada a un método es una expresión o no? Sabemos que los métodos devuelven un resultado, por lo que sí, son expresiones. De esto se deduce automáticamente muchas cosas interesantes. +## La llamada a un método como expresión -Por ejemplo, podemos utilizar una llamada a un método directamente en operaciones matemáticas. Así es como se puede obtener el índice del último carácter de una palabra: +Hablemos de los métodos. ¿Una llamada a un método es una expresión o no? Sabemos que los métodos devuelven un resultado, así que sí, una llamada a un método es una expresión. De esto se deduce automáticamente mucho de interés. + +Por ejemplo, podemos usar una llamada a un método directamente en operaciones matemáticas. Así se obtiene el índice del último carácter de una palabra: ```java // Los índices comienzan en cero var name = "Java"; -// ¡Llamada al método y resta juntos! +// Una llamada a un método y una resta juntas var lastIndex = name.length() - 1; System.out.println(lastIndex); // => 3 ``` -En este código no hay una nueva sintaxis. Simplemente hemos combinado partes conocidas basándonos en su naturaleza. Podemos ir aún más lejos: +En este código no hay una sintaxis nueva. Simplemente hemos unido partes ya conocidas, apoyándonos en su naturaleza. El método `length()` devuelve el número `4`, le restamos uno y obtenemos `3`. Podemos ir aún más lejos e integrar la llamada directamente en la impresión: ```java System.out.println(name.length() - 1); // => 3 ``` -Todo esto es válido para cualquier método, incluyendo los métodos de cadenas de texto: +## Las expresiones como argumentos de métodos + +El argumento de un método siempre es algún valor. Pero un valor no solo se puede escribir directamente, también se puede calcular. Y eso significa que en los argumentos se puede sustituir cualquier expresión. + +```java +// Aquí el argumento de println es el número 150 +System.out.println(150); + +// Y aquí el argumento es una expresión que primero se evalúa +System.out.println(10 * 15); // => 150 + +// Se puede combinar de forma aún más compleja +var rate = 10; +var hours = 15; +var bonus = 50; +System.out.println(rate * hours + bonus); // => 200 +``` + +El método `println()` recibe un valor ya listo y lo muestra en pantalla. Al método le da igual cómo se obtuvo ese valor. Por eso las llamadas a métodos combinan perfectamente con cualquier expresión. + +## La llamada a un método dentro de un método + +Dado que una llamada a un método es en sí misma una expresión, su resultado se puede pasar de inmediato a otro método. Esto permite construir construcciones aún más complejas: + +```java +var name = "Java"; + +// La llamada name.length() devuelve 4 +// Este resultado se usa de inmediato como argumento de println() +System.out.println(name.length()); // => 4 +``` + +Aquí `name.length()` se evalúa primero y devuelve el número `4`. Luego este valor se sustituye en la llamada `println()`. Para leer correctamente estas construcciones, hay que recordar el orden de evaluación. + +1. Primero se ejecuta el método que está "dentro", en nuestro caso `name.length()`. +2. Luego su resultado se sustituye en el lugar de la llamada. +3. Después de esto se ejecuta el método externo, en nuestro caso `println()`. + +El código `System.out.println(name.length())` se puede descomponer mentalmente así: + +```text +System.out.println("Java".length()) + +Paso 1: "Java".length() → 4 +Paso 2: println(4) → imprime 4 +``` + +Este principio funciona siempre. Primero se evalúan las llamadas anidadas, luego la externa. + +## Los métodos como parte de expresiones + +Los métodos devuelven valores, por eso sus llamadas se pueden usar como parte de cualquier otra expresión. Esto es válido para todos los métodos, incluidos los de cadenas: ```java var name = "Java"; // toUpperCase() convierte la palabra a mayúsculas System.out.println("Hola " + name.toUpperCase()); // => Hola JAVA + +// Se puede usar el resultado de un método en aritmética +var text = "hexlet"; +var doubled = text.length() * 2; +System.out.println(doubled); // => 12 ``` + +Aquí las llamadas `name.toUpperCase()` y `text.length()` son expresiones de pleno derecho. Devuelven valores que se combinan con cadenas, números, variables y otras operaciones. diff --git a/modules/35-methods-using/110-methods-as-expressions/es/data.yml b/modules/35-methods-using/110-methods-as-expressions/es/data.yml index 3e17e8f1..92f1805c 100644 --- a/modules/35-methods-using/110-methods-as-expressions/es/data.yml +++ b/modules/35-methods-using/110-methods-as-expressions/es/data.yml @@ -1,2 +1,7 @@ --- -name: Llamada al método - expresión +name: Llamada a un método — expresión +definitions: + - name: Expresión + description: >- + una secuencia de acciones sobre los datos que conduce a un resultado, el + cual se puede usar más adelante. diff --git a/modules/35-methods-using/115-string-immutability/en/EXERCISE.md b/modules/35-methods-using/115-string-immutability/en/EXERCISE.md new file mode 100644 index 00000000..95a0224c --- /dev/null +++ b/modules/35-methods-using/115-string-immutability/en/EXERCISE.md @@ -0,0 +1,7 @@ + +Data entered by users in forms often contains extra whitespace characters at the end or the beginning of the string. In addition, users can enter the same thing in different cases, which later interferes with working with the data. That is why, before adding them, the data is processed (they say normalized). Basic processing includes two actions: + +* Removing edge whitespace characters using the `.trim()` method, for example, it was: `" hexlet\n "`, it became: `"hexlet"` +* Converting to lowercase using the `toLowerCase()` method. It was: `"SUPPORT@hexlet.io"`, it became: `"support@hexlet.io"`. + +Update the `email` variable by writing into it the same value, but processed according to the scheme indicated above. Print what you got to the screen. diff --git a/modules/35-methods-using/115-string-immutability/en/README.md b/modules/35-methods-using/115-string-immutability/en/README.md new file mode 100644 index 00000000..4cbfdf74 --- /dev/null +++ b/modules/35-methods-using/115-string-immutability/en/README.md @@ -0,0 +1,67 @@ +Let's think about what the following code will print to the screen: + +```java +var company = "hexlet"; +company.toUpperCase(); // to uppercase +System.out.println(company); // => ? +``` + +It seems that the answer will be `"HEXLET"`, but that is not so. This program will print `"hexlet"`. Why? + +The thing is that strings in Java are **immutable** (or **unchangeable**). After creation, their content cannot be changed. There are no methods capable of changing the string itself. Any string method only returns a new string, while the original stays the same. + +## String methods do not change the original + +When we call a method on a string, it seems that we are changing it. For example, converting it to uppercase. In reality, the `toUpperCase()` method returns a new string in uppercase, while the original string does not change. + +```text +company = "hexlet" + +company.toUpperCase() → "HEXLET" (a new string) +company → "hexlet" (has not changed) +``` + +To avoid losing the result, let's save it in a variable: + +```java +var company = "hexlet"; +var upper = company.toUpperCase(); +System.out.println(upper); // => HEXLET +``` + +If you do not save the result of a method, it will simply be lost. Other methods work the same way: + +```java +var text = " hi "; +var cleaned = text.trim(); +System.out.println(cleaned); // => "hi", the result without spaces +System.out.println(text); // => " hi ", the string has not changed +``` + +The `trim()` method returned a new string without spaces at the edges, but `text` itself remained the same. + +The main reason for this behavior is performance. Strings and other primitive data types cannot be changed in almost any modern language. Immutability allows Java to reuse identical strings in memory and save resources. It also simplifies multithreaded code, where the same data is read by several threads at once. + +The second reason is related to the clarity of the code. When we do not change data but create new data based on the old, the code is easier to analyze and modify. Especially if the data goes through many transformations, which you will still encounter. It is impossible to accidentally change the value of a string, and this removes an entire class of errors. + +## How to change data + +But what should you do if the data needs to be changed? For this, it is enough to write the result of the method back into the same variable: + +```java +var language = "JAVA"; +language = language.toLowerCase(); +System.out.println(language); // => java +``` + +This is appropriate when the essence of the data does not change. After `toLowerCase()`, it is the same language, just in lowercase. + +On the other hand, in such a situation you can create a new variable with a different name: + +```java +var language = "JAVA"; +var processedLanguage = language.toLowerCase(); +System.out.println(processedLanguage); // => java +``` + +This approach is often preferable for reasons of readability. Variables that constantly change are harder to analyze. If the result of a method represents a different entity, it is worth giving it a separate name. In the end, it all depends on the task. With experience, an understanding of which approach is better will come. diff --git a/modules/35-methods-using/115-string-immutability/en/data.yml b/modules/35-methods-using/115-string-immutability/en/data.yml new file mode 100644 index 00000000..1c641136 --- /dev/null +++ b/modules/35-methods-using/115-string-immutability/en/data.yml @@ -0,0 +1,7 @@ +--- +name: String immutability +definitions: + - name: Immutability + description: >- + a property of data whereby its content cannot be changed after creation. + Methods return new data, while the original data stays the same. diff --git a/modules/35-methods-using/115-string-immutability/es/EXERCISE.md b/modules/35-methods-using/115-string-immutability/es/EXERCISE.md index 3d413aec..003d76f4 100644 --- a/modules/35-methods-using/115-string-immutability/es/EXERCISE.md +++ b/modules/35-methods-using/115-string-immutability/es/EXERCISE.md @@ -1,7 +1,7 @@ -Los datos ingresados por los usuarios en los formularios a menudo contienen espacios en blanco adicionales al principio o al final de la cadena. Además, los usuarios pueden ingresar lo mismo en diferentes casos, lo que luego dificulta el trabajo con los datos. Por lo tanto, antes de agregarlos, los datos se procesan (se dice que se normalizan). El procesamiento básico incluye dos acciones: +Los datos ingresados por los usuarios en los formularios a menudo contienen espacios en blanco adicionales al final o al inicio de la cadena. Además, los usuarios pueden ingresar lo mismo en distintas mayúsculas y minúsculas, lo que luego dificulta el trabajo con los datos. Por eso, antes de agregarlos, los datos se procesan (se dice que se normalizan). El procesamiento básico incluye dos acciones: -* Eliminar los espacios en blanco finales utilizando el método `.trim()`, por ejemplo, si era: `" hexlet\n "`, ahora es: `"hexlet"` -* Convertir a minúsculas utilizando el método `toLowerCase()`. Si era: `"SUPPORT@hexlet.io"`, ahora es: `"support@hexlet.io"`. +* Eliminar los espacios en blanco de los extremos con el método `.trim()`, por ejemplo, era: `" hexlet\n "`, quedó: `"hexlet"` +* Convertir a minúsculas con el método `toLowerCase()`. Era: `"SUPPORT@hexlet.io"`, quedó: `"support@hexlet.io"`. -Actualiza la variable `email` asignándole el mismo valor, pero procesado según el esquema mencionado anteriormente. Imprime en pantalla el resultado obtenido. +Actualiza la variable `email` escribiendo en ella el mismo valor, pero procesado según el esquema indicado arriba. Imprime en pantalla lo que obtuviste. diff --git a/modules/35-methods-using/115-string-immutability/es/README.md b/modules/35-methods-using/115-string-immutability/es/README.md index 9f0963d2..ac4e0775 100644 --- a/modules/35-methods-using/115-string-immutability/es/README.md +++ b/modules/35-methods-using/115-string-immutability/es/README.md @@ -2,19 +2,51 @@ Pensemos en qué mostrará en pantalla el siguiente código: ```java var company = "hexlet"; -company.toUpperCase(); // en mayúsculas +company.toUpperCase(); // a mayúsculas System.out.println(company); // => ? ``` -Parece que la respuesta será `"HEXLET"`, pero no es así. Este programa mostrará `"hexlet"` (compruébalo en [tryjshell](https://onecompiler.com/jshell)). ¿Por qué? +Parece que la respuesta será `"HEXLET"`, pero no es así. Este programa mostrará `"hexlet"`. ¿Por qué? -El motivo es que las cadenas en Java son inmutables. No hay forma ni métodos que puedan modificar la cadena en sí misma. Cualquier método de cadena solo puede devolver una nueva cadena. +El asunto es que las cadenas en Java son **inmutables** (o **no modificables**). Después de crearlas, su contenido no se puede cambiar. No existen métodos capaces de cambiar la propia cadena. Cualquier método de una cadena solo devuelve una nueva cadena, mientras que el original permanece igual. -La razón principal de esto es el rendimiento. Las cadenas y otros tipos de datos primitivos no se pueden modificar en prácticamente ningún lenguaje de programación moderno. +## Los métodos de las cadenas no cambian el original -La segunda razón está relacionada con la simplicidad del código. Cuando no modificamos los datos, sino que creamos nuevos datos basados en los antiguos, el código es más fácil de analizar y modificar. Especialmente cuando se realizan muchas manipulaciones con los datos, lo cual te encontrarás en el futuro. +Cuando llamamos a un método en una cadena, parece que la estamos cambiando. Por ejemplo, la convertimos a mayúsculas. En realidad, el método `toUpperCase()` devuelve una nueva cadena en mayúsculas, mientras que la cadena original no cambia. -Pero, ¿qué hacer si necesitamos cambiar los datos? Para ello, simplemente debemos reemplazar el valor de la variable: +```text +company = "hexlet" + +company.toUpperCase() → "HEXLET" (una cadena nueva) +company → "hexlet" (no ha cambiado) +``` + +Para no perder el resultado, guardémoslo en una variable: + +```java +var company = "hexlet"; +var upper = company.toUpperCase(); +System.out.println(upper); // => HEXLET +``` + +Si no se guarda el resultado de un método, simplemente se pierde. Otros métodos funcionan de la misma manera: + +```java +var text = " hi "; +var cleaned = text.trim(); +System.out.println(cleaned); // => "hi", el resultado sin espacios +System.out.println(text); // => " hi ", la cadena no ha cambiado +``` + +El método `trim()` devolvió una nueva cadena sin espacios en los bordes, pero el propio `text` permaneció igual. + +La razón principal de este comportamiento es el rendimiento. Las cadenas y otros tipos de datos primitivos no se pueden cambiar en casi ningún lenguaje moderno. La inmutabilidad permite a Java reutilizar cadenas idénticas en la memoria y ahorrar recursos. También simplifica el código multihilo, donde los mismos datos son leídos por varios hilos a la vez. + +La segunda razón está relacionada con la claridad del código. Cuando no cambiamos los datos, sino que creamos nuevos a partir de los antiguos, el código es más fácil de analizar y modificar. Sobre todo si con los datos ocurren muchas transformaciones, algo con lo que aún te toparás. Es imposible cambiar por accidente el valor de una cadena, y esto elimina toda una clase de errores. + +## Cómo cambiar los datos + +Pero ¿qué hacer si hay que cambiar los datos? Para ello basta con escribir el resultado del método de vuelta en la misma variable: ```java var language = "JAVA"; @@ -22,7 +54,9 @@ language = language.toLowerCase(); System.out.println(language); // => java ``` -Por otro lado, en una situación como esta, también podemos crear una nueva variable con un nombre diferente: +Esto es apropiado cuando la esencia de los datos no cambia. Después de `toLowerCase()`, es el mismo lenguaje, solo que en minúsculas. + +Por otro lado, en una situación así se puede crear una nueva variable con un nombre diferente: ```java var language = "JAVA"; @@ -30,4 +64,4 @@ var processedLanguage = language.toLowerCase(); System.out.println(processedLanguage); // => java ``` -Este enfoque a menudo es preferible por motivos de legibilidad. Las variables que cambian constantemente son más difíciles de analizar. Al final, todo depende de la tarea. Con la experiencia, se adquiere la comprensión de qué enfoque es mejor. +Este enfoque a menudo es preferible por motivos de legibilidad. Las variables que cambian constantemente son más difíciles de analizar. Si el resultado de un método representa otra entidad, conviene darle un nombre aparte. Al final, todo depende de la tarea. Con la experiencia llegará la comprensión de qué enfoque es mejor. diff --git a/modules/35-methods-using/115-string-immutability/es/data.yml b/modules/35-methods-using/115-string-immutability/es/data.yml index 4e8ef4c0..b1f2f078 100644 --- a/modules/35-methods-using/115-string-immutability/es/data.yml +++ b/modules/35-methods-using/115-string-immutability/es/data.yml @@ -1,2 +1,8 @@ --- name: Inmutabilidad de las cadenas +definitions: + - name: Inmutabilidad + description: >- + una propiedad de los datos por la cual su contenido no se puede cambiar + después de crearlos. Los métodos devuelven datos nuevos, mientras que los + originales permanecen igual. diff --git a/modules/35-methods-using/120-methods-chain/en/EXERCISE.md b/modules/35-methods-using/120-methods-chain/en/EXERCISE.md new file mode 100644 index 00000000..2fd0f5f3 --- /dev/null +++ b/modules/35-methods-using/120-methods-chain/en/EXERCISE.md @@ -0,0 +1,11 @@ + +Write code that takes data from the `name` variable and performs capitalization. In programming, this is the name for the operation that makes the first letter of a word uppercase and converts all the others to lowercase. For example: *heXlet => Hexlet*. The program should print the result to the screen. + +To extract parts of a word, use the [substring()](https://ru.hexlet.io/qna/java/questions/kak-izvlech-podstroku-iz-stroki-v-java?utm_source=code-basics&utm_medium=referral&utm_campaign=qna&utm_content=lesson) method: + +```java +// param 1 – the starting index, param 2 – the ending index (exclusive) +"hexlet".substring(0, 1); // "h" +// By default, up to the end of the string +"hexlet".substring(1); // "exlet" +``` diff --git a/modules/35-methods-using/120-methods-chain/en/README.md b/modules/35-methods-using/120-methods-chain/en/README.md new file mode 100644 index 00000000..4ade0837 --- /dev/null +++ b/modules/35-methods-using/120-methods-chain/en/README.md @@ -0,0 +1,107 @@ +Data processing can consist of a large number of steps that need to be performed one after another. + +Let's take as an example the following task: form a web page address based on the article title entered by the user. Such a task often arises when publishing articles in blogs. Such addresses look like this: + +```text +https://ru.hexlet.io/blog/posts/iz-vahtovika-v-programmirovanie +``` + +The last part here, *iz-vahtovika-v-programmirovanie*, is created automatically by code that we wrote at Hexlet. It has a special name — it is a [**slug**](https://en.wikipedia.org/wiki/Clean_URL#Slug). + +What steps need to be performed to get such a string? Here are just some of them: + +* Convert everything to lowercase, so that duplicates of identical pages are not accidentally created in search engines +* Clean the title of whitespace characters at the edges. They can accidentally appear during input +* Perform transliteration, because it is better to use Latin alphabet characters in addresses +* Cut out special characters like question marks and exclamation marks +* Replace spaces with hyphens + +Some of the steps require knowledge that is new to us, so we will skip them. The remaining steps will look approximately like this: + +```java +// The title entered by the user. In English for simplicity +var name = " How much is the fish? \n"; +// cut out the edge spaces and the line break +name = name.trim(); +// Remove the question mark +name = name.replace("?", ""); +// Replace spaces with a hyphen +name = name.replace(" ", "-"); +// Convert to lowercase +name = name.toLowerCase(); +System.out.println(name); // => how-much-is-the-fish +``` + +If you look closely at this code, you can notice a common pattern. A method returns data that we assign to a variable, and then we process it further down the chain. + +## Method chain + +This pattern can be simplified by removing the intermediate rewriting of the variable. A method returns a new string, and the next method is immediately applied to this string. This technique is called **method chaining**. + +```java +var name = " How much is the fish? "; +name = name.trim().replace("?", "").replace(" ", "-").toLowerCase(); +System.out.println(name); // => how-much-is-the-fish +``` + +The methods are called one after another, like links in a chain. This allows writing compact and readable code. If the chain becomes too long, it can be split into several lines: + +```java +name = name.trim() + .replace("?", "") + .replace(" ", "-") + .toLowerCase(); +``` + +Despite the convenience of this mechanism, it should not be overused. Intermediate variables sometimes make the code easier to understand. + +## Order of evaluation + +In a method chain, the order of execution goes from left to right. Each next method is called on the result of the previous one: + +```java +var text = " hExLeT "; +System.out.println(text.trim().toLowerCase().replace("h", "x")); // => xexlet +``` + +1. `" hExLeT "` is the original string. +2. `trim()` removes the spaces at the edges and returns `"hExLeT"`. +3. `toLowerCase()` converts to lowercase and returns `"hexlet"`. +4. `replace("h", "x")` replaces `"h"` with `"x"` and returns `"xexlet"`. + +The same result is obtained without a chain, through intermediate variables: + +```java +var text = " hExLeT "; +var step1 = text.trim(); // "hExLeT" +var step2 = step1.toLowerCase(); // "hexlet" +var step3 = step2.replace("h", "x"); // "xexlet" +System.out.println(step3); +``` + +Each method returns a new string, and the next method is applied to it. + +```text +" hExLeT ".trim().toLowerCase().replace("h", "x") + │ │ │ + ↓ ↓ ↓ + "hExLeT" │ │ + "hexlet" │ + "xexlet" +``` + +In the chain, you simply move from left to right, reading it like an ordinary sentence. If you mix up the order, the result may differ. For example, replacing spaces will work differently if you do it before removing the edge spaces. In some situations, the outcome will coincide by chance, in others the order will really affect the result. + +## Where the chain ends + +The chain can be continued as long as the result remains a string or another type that has methods. If a method returns a number or another primitive type, you can no longer call further methods: + +```java +var text = "hexlet"; +var index = text.toUpperCase().indexOf("E"); +System.out.println(index); // => 1 +``` + +The `indexOf()` method returns the number `1`, that is, the position of the first character `"E"` in the string `"HEXLET"`. A number has no string methods, so the chain ends here. + +Method chains serve as a convenient way to combine several operations on a value without intermediate variables. diff --git a/modules/35-methods-using/120-methods-chain/en/data.yml b/modules/35-methods-using/120-methods-chain/en/data.yml new file mode 100644 index 00000000..2a7c22bc --- /dev/null +++ b/modules/35-methods-using/120-methods-chain/en/data.yml @@ -0,0 +1,8 @@ +--- +name: Method call chains +definitions: + - name: Method chain + description: >- + a technique in which methods are called one after another, and each next + one is applied to the result of the previous one. For example, + `" Hexlet ".trim().toLowerCase()`. diff --git a/modules/35-methods-using/120-methods-chain/es/EXERCISE.md b/modules/35-methods-using/120-methods-chain/es/EXERCISE.md index d7a569c4..ae685086 100644 --- a/modules/35-methods-using/120-methods-chain/es/EXERCISE.md +++ b/modules/35-methods-using/120-methods-chain/es/EXERCISE.md @@ -1,10 +1,10 @@ -Escriba un código que tome los datos de la variable `name` y los capitalice. En programación, esto se llama capitalización, que convierte la primera letra de una palabra en mayúscula y el resto en minúsculas. Por ejemplo: *heXlet => Hexlet*. El programa debe imprimir el resultado en la pantalla. +Escribe un código que tome los datos de la variable `name` y realice la capitalización. En programación, así se llama la operación que pone en mayúscula la primera letra de una palabra y convierte todas las demás a minúsculas. Por ejemplo: *heXlet => Hexlet*. El programa debe mostrar el resultado en pantalla. -Para extraer partes de una palabra, use el método [substring()](https://ru.hexlet.io/qna/java/questions/kak-izvlech-podstroku-iz-stroki-v-java?utm_source=code-basics&utm_medium=referral&utm_campaign=qna&utm_content=lesson): +Para extraer partes de una palabra, usa el método [substring()](https://ru.hexlet.io/qna/java/questions/kak-izvlech-podstroku-iz-stroki-v-java?utm_source=code-basics&utm_medium=referral&utm_campaign=qna&utm_content=lesson): ```java -// El primer parámetro es el índice inicial, el segundo es el índice final (no incluido) +// parámetro 1 – el índice inicial, parámetro 2 – el índice final (no incluido) "hexlet".substring(0, 1); // "h" // Por defecto, hasta el final de la cadena "hexlet".substring(1); // "exlet" diff --git a/modules/35-methods-using/120-methods-chain/es/README.md b/modules/35-methods-using/120-methods-chain/es/README.md index a74af57d..d6e0e602 100644 --- a/modules/35-methods-using/120-methods-chain/es/README.md +++ b/modules/35-methods-using/120-methods-chain/es/README.md @@ -1,40 +1,42 @@ -El procesamiento de datos puede constar de una cantidad considerable de pasos que deben realizarse. +El procesamiento de datos puede constar de una gran cantidad de pasos que hay que realizar uno tras otro. -Tomemos como ejemplo la tarea de crear una dirección de página web basada en el nombre de un artículo ingresado por el usuario. Esta tarea a menudo surge al publicar artículos en blogs. Estas direcciones se ven así: +Tomemos como ejemplo la siguiente tarea: formar la dirección de una página web a partir del título de un artículo introducido por el usuario. Esta tarea surge a menudo al publicar artículos en blogs. Estas direcciones se ven así: ```text https://codica.la/blog/de-obrero-a-programador ``` -La última parte aquí, *de-obrero-a-programador*, se crea automáticamente con el código que hemos escrito en Hexlet. Por cierto, tiene un nombre especial: se llama [**slug**](https://en.wikipedia.org/wiki/Clean_URL#Slug). +La última parte aquí, *de-obrero-a-programador*, se crea automáticamente con el código que escribimos en Hexlet. Tiene un nombre especial: se llama [**slug**](https://es.wikipedia.org/wiki/URL_sem%C3%A1ntica). -¿Qué pasos se deben seguir para obtener una cadena similar? Aquí hay solo algunos de ellos: +¿Qué pasos hay que realizar para obtener una cadena similar? Aquí solo algunos de ellos: -* Convertir todo a minúsculas para evitar la creación accidental de duplicados de páginas en los motores de búsqueda. -* Limpiar el nombre de los espacios en blanco alrededor. Pueden aparecer accidentalmente al ingresar el nombre. -* Realizar transliteración. Es mejor que las direcciones solo contengan caracteres del alfabeto latino. -* Eliminar todos los caracteres especiales, como signos de interrogación, exclamaciones, etc. -* Reemplazar todos los espacios por guiones. +* Convertir todo a minúsculas, para que no se creen accidentalmente duplicados de páginas idénticas en los motores de búsqueda +* Limpiar el título de los espacios en blanco de los extremos. Pueden aparecer accidentalmente al escribir +* Realizar la transliteración, porque en las direcciones es mejor usar caracteres del alfabeto latino +* Recortar los caracteres especiales como los signos de interrogación y de exclamación +* Reemplazar los espacios por guiones -Algunos de estos pasos requieren conocimientos nuevos para nosotros, por lo que los omitiremos. Los demás pasos se verán más o menos así: +Algunos de los pasos requieren conocimientos nuevos para nosotros, por eso los omitiremos. Los demás pasos se verán más o menos así: ```java -// Nombre ingresado por el usuario. En inglés para mayor simplicidad +// Nombre introducido por el usuario. En inglés para simplificar var name = " How much is the fish? \n"; -// Eliminamos los espacios y saltos de línea al final +// recortamos los espacios de los extremos y el salto de línea name = name.trim(); // Eliminamos el signo de interrogación name = name.replace("?", ""); -// Reemplazamos los espacios por guiones +// Reemplazamos los espacios por un guion name = name.replace(" ", "-"); // Convertimos a minúsculas name = name.toLowerCase(); System.out.println(name); // => how-much-is-the-fish ``` -Si observamos detenidamente este código, podemos notar un patrón común. El método devuelve los datos que asignamos a la variable y luego los procesa en una cadena de llamadas de métodos. +Si observamos con atención este código, podemos notar un patrón común. Un método devuelve datos que asignamos a una variable, y luego los procesamos más adelante en la cadena. -Este patrón se puede simplificar eliminando la reasignación intermedia de la variable: +## La cadena de métodos + +Este patrón se puede simplificar eliminando la reescritura intermedia de la variable. Un método devuelve una nueva cadena, y a esta cadena se le aplica de inmediato el siguiente método. Esta técnica se llama **cadena de métodos (method chaining)**. ```java var name = " How much is the fish? "; @@ -42,7 +44,7 @@ name = name.trim().replace("?", "").replace(" ", "-").toLowerCase(); System.out.println(name); // => how-much-is-the-fish ``` -Gracias a que cada método devuelve una nueva cadena, podemos seguir procesándola llamando a los métodos uno tras otro. Si la cadena de métodos se vuelve demasiado larga, se puede dividir en varias líneas: +Los métodos se llaman uno tras otro, como eslabones de una cadena. Esto permite escribir un código compacto y legible. Si la cadena se vuelve demasiado larga, se puede dividir en varias líneas: ```java name = name.trim() @@ -51,4 +53,55 @@ name = name.trim() .toLowerCase(); ``` -A pesar de la conveniencia de este mecanismo, no se debe abusar de él. Las variables intermedias pueden facilitar la comprensión del código. +A pesar de la comodidad de este mecanismo, no conviene abusar de él. Las variables intermedias a veces facilitan la comprensión del código. + +## Orden de evaluación + +En una cadena de métodos, el orden de ejecución va de izquierda a derecha. Cada método siguiente se llama sobre el resultado del anterior: + +```java +var text = " hExLeT "; +System.out.println(text.trim().toLowerCase().replace("h", "x")); // => xexlet +``` + +1. `" hExLeT "` es la cadena original. +2. `trim()` elimina los espacios de los extremos y devuelve `"hExLeT"`. +3. `toLowerCase()` convierte a minúsculas y devuelve `"hexlet"`. +4. `replace("h", "x")` reemplaza `"h"` por `"x"` y devuelve `"xexlet"`. + +El mismo resultado se obtiene sin la cadena, mediante variables intermedias: + +```java +var text = " hExLeT "; +var step1 = text.trim(); // "hExLeT" +var step2 = step1.toLowerCase(); // "hexlet" +var step3 = step2.replace("h", "x"); // "xexlet" +System.out.println(step3); +``` + +Cada método devuelve una nueva cadena, y el siguiente método se aplica ya sobre ella. + +```text +" hExLeT ".trim().toLowerCase().replace("h", "x") + │ │ │ + ↓ ↓ ↓ + "hExLeT" │ │ + "hexlet" │ + "xexlet" +``` + +En la cadena simplemente te mueves de izquierda a derecha, leyéndola como una oración común. Si se confunde el orden, el resultado puede diferir. Por ejemplo, el reemplazo de los espacios funcionará de otra manera si se hace antes de eliminar los espacios de los extremos. En unas situaciones el resultado coincidirá por casualidad, en otras el orden realmente influirá en el resultado. + +## Dónde termina la cadena + +La cadena se puede continuar mientras el resultado siga siendo una cadena u otro tipo que tenga métodos. Si un método devuelve un número u otro tipo primitivo, ya no se pueden llamar más métodos: + +```java +var text = "hexlet"; +var index = text.toUpperCase().indexOf("E"); +System.out.println(index); // => 1 +``` + +El método `indexOf()` devuelve el número `1`, es decir, la posición del primer carácter `"E"` en la cadena `"HEXLET"`. Un número no tiene métodos de cadena, por eso la cadena termina aquí. + +Las cadenas de métodos sirven como una forma cómoda de combinar varias operaciones sobre un valor sin variables intermedias. diff --git a/modules/35-methods-using/120-methods-chain/es/data.yml b/modules/35-methods-using/120-methods-chain/es/data.yml index 3382da09..524104b4 100644 --- a/modules/35-methods-using/120-methods-chain/es/data.yml +++ b/modules/35-methods-using/120-methods-chain/es/data.yml @@ -1,2 +1,8 @@ --- -name: Cadenas de llamadas de métodos +name: Cadenas de llamadas a métodos +definitions: + - name: Cadena de métodos + description: >- + una técnica en la que los métodos se llaman uno tras otro, y cada + siguiente se aplica al resultado del anterior. Por ejemplo, + `" Hexlet ".trim().toLowerCase()`. diff --git a/modules/35-methods-using/130-string-symbols/en/EXERCISE.md b/modules/35-methods-using/130-string-symbols/en/EXERCISE.md new file mode 100644 index 00000000..bf5fa2c6 --- /dev/null +++ b/modules/35-methods-using/130-string-symbols/en/EXERCISE.md @@ -0,0 +1,7 @@ +Print the second character of the string `"Hexlet"` to the screen. Use the `charAt()` method and remember that indexes start from zero. + +Expected output: + +```text +e +``` diff --git a/modules/35-methods-using/130-string-symbols/en/README.md b/modules/35-methods-using/130-string-symbols/en/README.md new file mode 100644 index 00000000..97223e34 --- /dev/null +++ b/modules/35-methods-using/130-string-symbols/en/README.md @@ -0,0 +1,65 @@ +Sometimes you need to extract a single character from a string. A site knows a user's first and last name, but wants to display them in a shortened form, A. Ivanov. To do this, you take the first letter of the name and put a dot next to it. + +In Java, every character of a string has its own number, which is called an index. Counting starts from zero. The first character has index `0`, the second `1`, and so on in order. To extract a character by index, you call the `charAt()` method on the string. Inside the parentheses, you specify the needed index. + +```java +var firstName = "Alexander"; +System.out.println(firstName.charAt(0)); // => A +``` + +The `charAt()` method is called on the string through a dot. In the parentheses there is the argument `0`, so the method returns the very first character. The structure is the same as for other string methods. First the object, then a dot, then the method name and parentheses with the argument. + +The relationship between characters and their indexes can be seen in the diagram: + +```text +Character A l e x a n d e r +Index 0 1 2 3 4 5 6 7 8 +``` + +The length of the string `Alexander` is `9`, so the index of the last character is `8`, that is `9 - 1`. To extract the last character, you pass exactly this index: + +```java +var firstName = "Alexander"; +System.out.println(firstName.charAt(8)); // => r +``` + +## What the method returns + +The `charAt()` method returns a single character. In Java there is a separate data type `char` for a single character. A value of type `char` is written in single quotes, for example `'A'`. A string in double quotes and a single character in single quotes belong to different types. + +```java +var firstName = "Alexander"; +var letter = firstName.charAt(0); +System.out.println(letter); // => A +``` + +Here the result of the call is saved in the variable `letter`. This is convenient when the character is needed further in the code. But the variable is not required; the method can be printed right away: + +```java +System.out.println("Hexlet".charAt(0)); // => H +``` + +The method is called directly on the string literal `"Hexlet"`. First `charAt(0)` is evaluated, then the result goes into `println()`. + +## Going out of the string bounds + +The index must fall inside the string. If you pass an index greater than the last one, the program terminates with an error: + +```java +var firstName = "Alexander"; +System.out.println(firstName.charAt(9)); +// StringIndexOutOfBoundsException +``` + +The string `Alexander` has nine characters with indexes from `0` to `8`. There is no index `9`, so the method throws a `StringIndexOutOfBoundsException` error. That is why, when working with characters, you first check the length of the string and access a character only when the index is definitely within the bounds. This technique is covered later in the course. + +## Special characters + +The `charAt()` method counts all characters in a row. Not only letters and signs, but also special characters. Each of them occupies its own position and has an index, even if it is not visible on the screen. + +For example, in the string `"\nyou"` at index `0` there is `\n` (a line break), and at index `1` comes the letter `y`. That is why the call `magic.charAt(1)` returns exactly `y`. + +```java +var magic = "\nyou"; +System.out.println(magic.charAt(1)); // => y +``` diff --git a/modules/35-methods-using/130-string-symbols/en/data.yml b/modules/35-methods-using/130-string-symbols/en/data.yml new file mode 100644 index 00000000..a78e1f66 --- /dev/null +++ b/modules/35-methods-using/130-string-symbols/en/data.yml @@ -0,0 +1,10 @@ +--- +name: String characters +tips: [] +definitions: + - name: Index + description: the position of a character inside a string, counting starts from zero. + - name: charAt + description: >- + a string method that returns the character at the specified index, for + example `"Hexlet".charAt(0)` returns `H`. diff --git a/modules/35-methods-using/130-string-symbols/es/EXERCISE.md b/modules/35-methods-using/130-string-symbols/es/EXERCISE.md new file mode 100644 index 00000000..5cca0d08 --- /dev/null +++ b/modules/35-methods-using/130-string-symbols/es/EXERCISE.md @@ -0,0 +1,7 @@ +Imprime en pantalla el segundo carácter de la cadena `"Hexlet"`. Usa el método `charAt()` y recuerda que los índices empiezan desde cero. + +Salida esperada: + +```text +e +``` diff --git a/modules/35-methods-using/130-string-symbols/es/README.md b/modules/35-methods-using/130-string-symbols/es/README.md new file mode 100644 index 00000000..c5f9892c --- /dev/null +++ b/modules/35-methods-using/130-string-symbols/es/README.md @@ -0,0 +1,65 @@ +A veces necesitas extraer un solo carácter de una cadena. Un sitio conoce el nombre y el apellido de un usuario, pero quiere mostrarlos de forma abreviada, A. Ivanov. Para ello, se toma la primera letra del nombre y se coloca un punto al lado. + +En Java, cada carácter de una cadena tiene su propio número, que se llama índice. El conteo empieza desde cero. El primer carácter tiene el índice `0`, el segundo `1`, y así sucesivamente. Para extraer un carácter por su índice, se llama al método `charAt()` de la cadena. Dentro de los paréntesis se indica el índice deseado. + +```java +var firstName = "Alexander"; +System.out.println(firstName.charAt(0)); // => A +``` + +El método `charAt()` se llama en la cadena a través de un punto. En los paréntesis está el argumento `0`, por lo que el método devuelve el primer carácter. La estructura es la misma que en otros métodos de cadena. Primero el objeto, luego un punto, después el nombre del método y los paréntesis con el argumento. + +La relación entre los caracteres y sus índices se ve en el diagrama: + +```text +Carácter A l e x a n d e r +Índice 0 1 2 3 4 5 6 7 8 +``` + +La longitud de la cadena `Alexander` es `9`, por lo que el índice del último carácter es `8`, es decir, `9 - 1`. Para extraer el último carácter, se pasa exactamente ese índice: + +```java +var firstName = "Alexander"; +System.out.println(firstName.charAt(8)); // => r +``` + +## Qué devuelve el método + +El método `charAt()` devuelve un solo carácter. En Java existe un tipo de dato aparte, `char`, para un carácter individual. Un valor de tipo `char` se escribe entre comillas simples, por ejemplo `'A'`. Una cadena entre comillas dobles y un carácter individual entre comillas simples pertenecen a tipos diferentes. + +```java +var firstName = "Alexander"; +var letter = firstName.charAt(0); +System.out.println(letter); // => A +``` + +Aquí el resultado de la llamada se guarda en la variable `letter`. Esto es cómodo cuando el carácter se necesita más adelante en el código. Pero la variable no es obligatoria; el método se puede imprimir de inmediato: + +```java +System.out.println("Hexlet".charAt(0)); // => H +``` + +El método se llama directamente en el literal de cadena `"Hexlet"`. Primero se evalúa `charAt(0)`, luego el resultado pasa a `println()`. + +## Salida fuera de los límites de la cadena + +El índice debe caer dentro de la cadena. Si pasas un índice mayor que el último, el programa termina con un error: + +```java +var firstName = "Alexander"; +System.out.println(firstName.charAt(9)); +// StringIndexOutOfBoundsException +``` + +La cadena `Alexander` tiene nueve caracteres con índices del `0` al `8`. No existe el índice `9`, por lo que el método lanza el error `StringIndexOutOfBoundsException`. Por eso, al trabajar con caracteres, primero se comprueba la longitud de la cadena y se accede a un carácter solo cuando el índice está definitivamente dentro de los límites. Esta técnica se estudia más adelante en el curso. + +## Caracteres especiales + +El método `charAt()` cuenta todos los caracteres seguidos. No solo las letras y los signos, sino también los caracteres especiales. Cada uno de ellos ocupa su propia posición y tiene un índice, aunque no se vea en la pantalla. + +Por ejemplo, en la cadena `"\nyou"` en el índice `0` está `\n` (un salto de línea), y en el índice `1` ya viene la letra `y`. Por eso, la llamada `magic.charAt(1)` devuelve exactamente `y`. + +```java +var magic = "\nyou"; +System.out.println(magic.charAt(1)); // => y +``` diff --git a/modules/35-methods-using/130-string-symbols/es/data.yml b/modules/35-methods-using/130-string-symbols/es/data.yml new file mode 100644 index 00000000..9637c039 --- /dev/null +++ b/modules/35-methods-using/130-string-symbols/es/data.yml @@ -0,0 +1,10 @@ +--- +name: Caracteres de una cadena +tips: [] +definitions: + - name: Índice + description: la posición de un carácter dentro de una cadena, el conteo empieza desde cero. + - name: charAt + description: >- + método de cadena que devuelve el carácter en el índice indicado, por + ejemplo `"Hexlet".charAt(0)` devuelve `H`. diff --git a/modules/35-methods-using/140-string-substring/en/EXERCISE.md b/modules/35-methods-using/140-string-substring/en/EXERCISE.md new file mode 100644 index 00000000..eb0f7fc7 --- /dev/null +++ b/modules/35-methods-using/140-string-substring/en/EXERCISE.md @@ -0,0 +1,7 @@ +A variable holds the string `"Hexlet"`. Extract the first three characters from it using the `substring()` method and print the substring to the screen. + +Expected output: + +```text +Hex +``` diff --git a/modules/35-methods-using/140-string-substring/en/README.md b/modules/35-methods-using/140-string-substring/en/README.md new file mode 100644 index 00000000..1f4625b3 --- /dev/null +++ b/modules/35-methods-using/140-string-substring/en/README.md @@ -0,0 +1,77 @@ +When working with strings, we often solve the same task — extract a part of the string. Get the year from a date, the name from a full name, or the first characters from an email address. In Java, the string has the `substring()` method for this. + +## What a substring is + +A substring is a part of a string that is contained inside another string. In the string `"12-08-2034"`, a substring can be `"2034"`, `"12"`, or even `"-"`. It all depends on what information you need to extract. + +Suppose only the year `"2034"` is needed. Each character of the string has its own index (position), counting starts from zero: + +```text +'1' '2' '-' '0' '8' '-' '2' '0' '3' '4' + 0 1 2 3 4 5 6 7 8 9 +``` + +The year starts at index `6` and ends at `9`. To extract it, you call the `substring()` method on the string with two arguments: + +```java +var value = "12-08-2034"; +var year = value.substring(6, 10); +System.out.println(year); // => 2034 +``` + +The method is called on the string through a dot. The first argument sets the start index, the second sets the end index. The call format is: + +```java +string.substring(start, end) +``` + +The character at the start index is included in the result, but the character at the end index is not. It is convenient to think of the end as the ordinal number of the character you want to take as the last one. + +```java +var value = "code-basics"; + +System.out.println(value.substring(5, 11)); // => basics (indexes 5 through 10) +System.out.println(value.substring(0, 7)); // => code-ba (indexes 0 through 6) +System.out.println(value.substring(2, 6)); // => de-b +``` + +How do you count all this? When working with a specific string, we almost always count by eye. + +## A substring is also a string + +The `substring()` method returns a string, even if there are only digits inside. So the result is used as an ordinary string — printed, joined, passed to other methods. The result of one call can be passed straight into the next: + +```java +var value = "01-12-9873"; + +var part = value.substring(3, 7); // => 12-9 +System.out.println(part.substring(0, 2)); // => 12 +``` + +First we got the substring `"12-9"`, and then extracted a new substring `"12"` from it. + +## A substring to the end of the string + +Sometimes a part of the string is needed from some character all the way to the end. For this, `substring()` has a variant with one argument. It sets only the start index, and the method itself takes the end equal to the end of the string. + +```java +var value = "Hexlet"; + +System.out.println(value.substring(3)); // => let (from character 3 to the end) +``` + +The call `value.substring(3)` takes characters from index `3` and further to the end of the string. The length of the string `"Hexlet"` is `6`, so `value.substring(3)` and `value.substring(3, 6)` give the same result `let`. When the end matches the length of the string, the second argument can be omitted. + +## Going out of the string bounds + +The indexes must fall inside the string. If you pass an index greater than the string length, the method throws an error: + +```java +var value = "Hexlet"; +System.out.println(value.substring(0, 10)); +// StringIndexOutOfBoundsException +``` + +The string `"Hexlet"` has six characters, so the end index cannot be greater than `6`. We passed `10`, and the method terminated with a `StringIndexOutOfBoundsException` error. Before the call, you should make sure that the indexes are within the string bounds. + +The main thing is to understand the basic structure `string.substring(start, end)`, and in practice these calls will quickly become a habit. diff --git a/modules/35-methods-using/140-string-substring/en/data.yml b/modules/35-methods-using/140-string-substring/en/data.yml new file mode 100644 index 00000000..8a14f1d2 --- /dev/null +++ b/modules/35-methods-using/140-string-substring/en/data.yml @@ -0,0 +1,11 @@ +--- +name: Substring +tips: [] +definitions: + - name: Substring + description: a part of a string that is contained inside another string. + - name: substring + description: >- + a string method that returns a substring by the start and end indexes. The + character at the start index is included in the result, the character at the + end index is not, for example `"Hexlet".substring(0, 3)` returns `Hex`. diff --git a/modules/35-methods-using/140-string-substring/es/EXERCISE.md b/modules/35-methods-using/140-string-substring/es/EXERCISE.md new file mode 100644 index 00000000..e769f3e0 --- /dev/null +++ b/modules/35-methods-using/140-string-substring/es/EXERCISE.md @@ -0,0 +1,7 @@ +Una variable contiene la cadena `"Hexlet"`. Extrae de ella los primeros tres caracteres con el método `substring()` e imprime la subcadena en pantalla. + +Salida esperada: + +```text +Hex +``` diff --git a/modules/35-methods-using/140-string-substring/es/README.md b/modules/35-methods-using/140-string-substring/es/README.md new file mode 100644 index 00000000..1ed316dc --- /dev/null +++ b/modules/35-methods-using/140-string-substring/es/README.md @@ -0,0 +1,77 @@ +Al trabajar con cadenas, a menudo resolvemos la misma tarea: extraer una parte de la cadena. Obtener el año de una fecha, el nombre de un nombre completo o los primeros caracteres de una dirección de correo electrónico. En Java, la cadena tiene el método `substring()` para esto. + +## Qué es una subcadena + +Una subcadena es una parte de una cadena que está contenida dentro de otra cadena. En la cadena `"12-08-2034"`, una subcadena puede ser `"2034"`, `"12"` o incluso `"-"`. Todo depende de qué información se necesite extraer. + +Supongamos que solo se necesita el año `"2034"`. Cada carácter de la cadena tiene su propio índice (posición), el conteo empieza desde cero: + +```text +'1' '2' '-' '0' '8' '-' '2' '0' '3' '4' + 0 1 2 3 4 5 6 7 8 9 +``` + +El año empieza en el índice `6` y termina en el `9`. Para extraerlo, se llama al método `substring()` de la cadena con dos argumentos: + +```java +var value = "12-08-2034"; +var year = value.substring(6, 10); +System.out.println(year); // => 2034 +``` + +El método se llama en la cadena a través de un punto. El primer argumento indica el índice de inicio, el segundo indica el índice de fin. El formato de la llamada es así: + +```java +cadena.substring(inicio, fin) +``` + +El carácter con el índice de inicio se incluye en el resultado, pero el carácter con el índice de fin no. Es cómodo pensar en el fin como el número de orden del carácter que se debe tomar como último. + +```java +var value = "code-basics"; + +System.out.println(value.substring(5, 11)); // => basics (del índice 5 al 10) +System.out.println(value.substring(0, 7)); // => code-ba (del índice 0 al 6) +System.out.println(value.substring(2, 6)); // => de-b +``` + +¿Cómo se calcula todo esto? Cuando trabajamos con una cadena concreta, casi siempre lo calculamos a ojo. + +## Una subcadena también es una cadena + +El método `substring()` devuelve una cadena, incluso si dentro solo hay dígitos. Esto significa que el resultado se usa como una cadena normal: se imprime, se une, se pasa a otros métodos. El resultado de una llamada se puede pasar directamente a la siguiente: + +```java +var value = "01-12-9873"; + +var part = value.substring(3, 7); // => 12-9 +System.out.println(part.substring(0, 2)); // => 12 +``` + +Primero obtuvimos la subcadena `"12-9"`, y luego extrajimos de ella una nueva subcadena `"12"`. + +## Una subcadena hasta el final de la cadena + +A veces se necesita una parte de la cadena desde algún carácter hasta el final. Para esto, `substring()` tiene una variante con un solo argumento. Este indica solo el índice de inicio, y el método toma el fin como igual al final de la cadena. + +```java +var value = "Hexlet"; + +System.out.println(value.substring(3)); // => let (del carácter 3 hasta el final) +``` + +La llamada `value.substring(3)` toma los caracteres desde el índice `3` y en adelante hasta el final de la cadena. La longitud de la cadena `"Hexlet"` es `6`, por lo que `value.substring(3)` y `value.substring(3, 6)` dan el mismo resultado `let`. Cuando el fin coincide con la longitud de la cadena, el segundo argumento se puede omitir. + +## Salida fuera de los límites de la cadena + +Los índices deben caer dentro de la cadena. Si pasas un índice mayor que la longitud de la cadena, el método lanza un error: + +```java +var value = "Hexlet"; +System.out.println(value.substring(0, 10)); +// StringIndexOutOfBoundsException +``` + +La cadena `"Hexlet"` tiene seis caracteres, por lo que el índice de fin no puede ser mayor que `6`. Pasamos `10`, y el método terminó con el error `StringIndexOutOfBoundsException`. Antes de la llamada, conviene asegurarse de que los índices estén dentro de los límites de la cadena. + +Lo principal es entender la estructura básica `cadena.substring(inicio, fin)`, y en la práctica estas llamadas se convertirán rápidamente en un hábito. diff --git a/modules/35-methods-using/140-string-substring/es/data.yml b/modules/35-methods-using/140-string-substring/es/data.yml new file mode 100644 index 00000000..909c26a2 --- /dev/null +++ b/modules/35-methods-using/140-string-substring/es/data.yml @@ -0,0 +1,12 @@ +--- +name: Subcadena +tips: [] +definitions: + - name: Subcadena + description: una parte de una cadena que está contenida dentro de otra cadena. + - name: substring + description: >- + método de cadena que devuelve una subcadena según los índices de inicio y + fin. El carácter con el índice de inicio se incluye en el resultado, el + carácter con el índice de fin no, por ejemplo `"Hexlet".substring(0, 3)` + devuelve `Hex`. diff --git a/modules/35-methods-using/150-string-format/App.java b/modules/35-methods-using/150-string-format/App.java index e97e9fe9..9dd0dde9 100644 --- a/modules/35-methods-using/150-string-format/App.java +++ b/modules/35-methods-using/150-string-format/App.java @@ -1,7 +1,7 @@ public class App { public static void main(String[] args) { // BEGIN - System.out.println(String.format("Привет, %s!", "Мир")); + System.out.println(String.format("Hello, %s!", "World")); // END } } diff --git a/modules/35-methods-using/150-string-format/AppTest.java b/modules/35-methods-using/150-string-format/AppTest.java index 44423403..d31f5be9 100644 --- a/modules/35-methods-using/150-string-format/AppTest.java +++ b/modules/35-methods-using/150-string-format/AppTest.java @@ -7,7 +7,7 @@ class AppTest { public static void main(String[] args) { - final var expected = "Привет, Мир!"; + final var expected = "Hello, World!"; ByteArrayOutputStream out = new ByteArrayOutputStream(); System.setOut(new PrintStream(out)); diff --git a/modules/35-methods-using/150-string-format/en/EXERCISE.md b/modules/35-methods-using/150-string-format/en/EXERCISE.md new file mode 100644 index 00000000..a8707b07 --- /dev/null +++ b/modules/35-methods-using/150-string-format/en/EXERCISE.md @@ -0,0 +1,7 @@ +Build a greeting from a template. Substitute the word `"World"` into the template `"Hello, %s!"` using the `String.format()` method and print the result on the screen. + +Expected output: + +```text +Hello, World! +``` diff --git a/modules/35-methods-using/150-string-format/en/README.md b/modules/35-methods-using/150-string-format/en/README.md new file mode 100644 index 00000000..52b9ba82 --- /dev/null +++ b/modules/35-methods-using/150-string-format/en/README.md @@ -0,0 +1,63 @@ +Let's recall how concatenation works. The needed strings and variables holding strings are joined with the `+` sign. + +```java +var firstName = "Joffrey"; +var greeting = "Hello"; + +System.out.println(greeting + ", " + firstName + "!"); +// => Hello, Joffrey! +``` + +In complex expressions, it's hard to immediately tell from such code what text will come out. Spaces, commas, and quotes start to get in the way of comprehension. Even this example takes a little effort to read the resulting string. + +That's why many languages have a separate way to build a string from a template and values. The template sets the shape of the future string, and the needed data is substituted in place of the markers. In Java, the `String.format()` method is called for this. + +```java +var firstName = "Joffrey"; +var greeting = "Hello"; + +System.out.println(String.format("%s, %s!", greeting, firstName)); +// => Hello, Joffrey! +``` + +The first argument of `String.format()` is the template. Inside the template there are `%s` markers; the remaining arguments are substituted in their places in order. The first `%s` is replaced with `greeting`, the second with `firstName`. The `%s` marker means the value is substituted as a string. + +```text +String.format("%s, %s!", greeting, firstName) + └┬┘ └┬┘ + "Hello" "Joffrey" → "Hello, Joffrey!" +``` + +In the template version, the text reads as a whole. Spaces, commas, and the exclamation mark are visible right away, whereas in a chain of `+` they drown among the quotes. + +## The formatted method + +The same action has a second form of notation. The `formatted()` method is called directly on the template string through a dot, and the values are passed in parentheses. + +```java +var firstName = "Joffrey"; +var greeting = "Hello"; + +System.out.println("%s, %s!".formatted(greeting, firstName)); +// => Hello, Joffrey! +``` + +Here the template `"%s, %s!"` is to the left of the dot, and `formatted()` substitutes the arguments into it. The result is the same as with `String.format()`. These two ways do the same thing; choose whichever you like. + +## An example with a number + +The `%s` marker substitutes not only strings. A number can be placed in its spot, and it will turn into a string by itself. + +```java +var school = "Hexlet"; +var year = 2012; + +var about = String.format("%s has been running since %s", school, year); +System.out.println(about); // => Hexlet has been running since 2012 +``` + +The method built a ready string from the template and arguments and returned it. The result was saved into the `about` variable and printed on the screen. + +## Why this is convenient + +The template looks almost the same as the resulting string. You can see where spaces and punctuation marks will go, you can see where the values will be substituted. It's easier to understand from such code what the output will be. That's why in most tasks, building a string from a template is preferred over a long chain of concatenations. diff --git a/modules/35-methods-using/150-string-format/en/data.yml b/modules/35-methods-using/150-string-format/en/data.yml new file mode 100644 index 00000000..1ac96fcc --- /dev/null +++ b/modules/35-methods-using/150-string-format/en/data.yml @@ -0,0 +1,11 @@ +--- +name: String formatting +tips: [] +definitions: + - name: Template + description: >- + a string with `%s` markers, in whose places values are substituted. + - name: String.format + description: >- + a method that builds a string from a template and values, for example + `String.format("Hello, %s!", "World")` returns `Hello, World!`. diff --git a/modules/35-methods-using/150-string-format/es/EXERCISE.md b/modules/35-methods-using/150-string-format/es/EXERCISE.md new file mode 100644 index 00000000..e1868aa4 --- /dev/null +++ b/modules/35-methods-using/150-string-format/es/EXERCISE.md @@ -0,0 +1,7 @@ +Construye un saludo a partir de una plantilla. Sustituye la palabra `"World"` en la plantilla `"Hello, %s!"` con el método `String.format()` y muestra el resultado en la pantalla. + +Salida esperada: + +```text +Hello, World! +``` diff --git a/modules/35-methods-using/150-string-format/es/README.md b/modules/35-methods-using/150-string-format/es/README.md new file mode 100644 index 00000000..e687e2a5 --- /dev/null +++ b/modules/35-methods-using/150-string-format/es/README.md @@ -0,0 +1,63 @@ +Recordemos cómo funciona la concatenación. Las cadenas necesarias y las variables con cadenas dentro se unen con el signo `+`. + +```java +var firstName = "Joffrey"; +var greeting = "Hello"; + +System.out.println(greeting + ", " + firstName + "!"); +// => Hello, Joffrey! +``` + +En expresiones complejas, con ese código cuesta entender de inmediato qué texto saldrá. Los espacios, las comas y las comillas empiezan a entorpecer la lectura. Incluso este ejemplo requiere un pequeño esfuerzo para leer la cadena final. + +Por eso, en muchos lenguajes existe una forma aparte de construir una cadena a partir de una plantilla y valores. La plantilla define la forma de la futura cadena, y en el lugar de las marcas se sustituyen los datos necesarios. En Java, para esto se llama al método `String.format()`. + +```java +var firstName = "Joffrey"; +var greeting = "Hello"; + +System.out.println(String.format("%s, %s!", greeting, firstName)); +// => Hello, Joffrey! +``` + +El primer argumento de `String.format()` es la plantilla. Dentro de la plantilla hay marcas `%s`, en cuyos lugares se sustituyen los demás argumentos por orden. El primer `%s` se reemplaza por `greeting`, el segundo por `firstName`. La marca `%s` significa que el valor se sustituye como una cadena. + +```text +String.format("%s, %s!", greeting, firstName) + └┬┘ └┬┘ + "Hello" "Joffrey" → "Hello, Joffrey!" +``` + +En la versión con plantilla, el texto se lee de forma completa. Los espacios, las comas y el signo de exclamación se ven de inmediato, mientras que en una cadena de `+` se pierden entre las comillas. + +## El método formatted + +La misma acción tiene una segunda forma de notación. El método `formatted()` se llama directamente sobre la cadena-plantilla a través de un punto, y los valores se pasan entre paréntesis. + +```java +var firstName = "Joffrey"; +var greeting = "Hello"; + +System.out.println("%s, %s!".formatted(greeting, firstName)); +// => Hello, Joffrey! +``` + +Aquí la plantilla `"%s, %s!"` está a la izquierda del punto, y `formatted()` le sustituye los argumentos. El resultado es el mismo que con `String.format()`. Estas dos formas hacen lo mismo; elige la que prefieras. + +## Un ejemplo con un número + +La marca `%s` no sustituye solo cadenas. En su lugar se puede poner un número, y se convertirá en cadena por sí mismo. + +```java +var school = "Hexlet"; +var year = 2012; + +var about = String.format("%s funciona desde %s", school, year); +System.out.println(about); // => Hexlet funciona desde 2012 +``` + +El método construyó una cadena lista a partir de la plantilla y los argumentos, y la devolvió. El resultado se guardó en la variable `about` y se mostró en la pantalla. + +## Por qué es cómodo + +La plantilla se ve casi igual que la cadena final. Se ve dónde irán los espacios y los signos de puntuación, se ve dónde se sustituirán los valores. Con ese código es más fácil entender qué saldrá. Por eso, en la mayoría de las tareas se prefiere construir la cadena a partir de una plantilla antes que una larga cadena de concatenaciones. diff --git a/modules/35-methods-using/150-string-format/es/data.yml b/modules/35-methods-using/150-string-format/es/data.yml new file mode 100644 index 00000000..0509353c --- /dev/null +++ b/modules/35-methods-using/150-string-format/es/data.yml @@ -0,0 +1,11 @@ +--- +name: Formateo de cadenas +tips: [] +definitions: + - name: Plantilla + description: >- + cadena con marcas `%s`, en cuyos lugares se sustituyen valores. + - name: String.format + description: >- + método que construye una cadena a partir de una plantilla y valores, por + ejemplo `String.format("Hello, %s!", "World")` devuelve `Hello, World!`. diff --git a/modules/35-methods-using/150-string-format/ru/EXERCISE.md b/modules/35-methods-using/150-string-format/ru/EXERCISE.md index f2146cb5..773ab32e 100644 --- a/modules/35-methods-using/150-string-format/ru/EXERCISE.md +++ b/modules/35-methods-using/150-string-format/ru/EXERCISE.md @@ -1,7 +1,7 @@ -Соберите приветствие по шаблону. Подставьте в шаблон `"Привет, %s!"` слово `"Мир"` с помощью метода `String.format()` и выведите результат на экран. +Соберите приветствие по шаблону. Подставьте в шаблон `"Hello, %s!"` слово `"World"` с помощью метода `String.format()` и выведите результат на экран. Ожидаемый вывод: ```text -Привет, Мир! +Hello, World! ``` diff --git a/modules/35-methods-using/200-methods-deterministic/en/EXERCISE.md b/modules/35-methods-using/200-methods-deterministic/en/EXERCISE.md new file mode 100644 index 00000000..6299bef0 --- /dev/null +++ b/modules/35-methods-using/200-methods-deterministic/en/EXERCISE.md @@ -0,0 +1,10 @@ + +The `Math.random()` method returns a random number between 0 and 1 with many digits after the decimal point. But in real tasks you sometimes need to get random integers. Implement the code that prints a random integer between 0 and 10 to the screen. To get such a number, you need to multiply the result of calling `Math.random()` by 10 and convert the type of the resulting number from *double* to *int*. + +```java +// Conversion to int +(int) 0.932342; // 0 +(int) 8.123412; // 8 +``` + +Try to solve this exercise in one line. diff --git a/modules/35-methods-using/200-methods-deterministic/en/README.md b/modules/35-methods-using/200-methods-deterministic/en/README.md new file mode 100644 index 00000000..2522a851 --- /dev/null +++ b/modules/35-methods-using/200-methods-deterministic/en/README.md @@ -0,0 +1,42 @@ +Methods in any programming language have fundamental properties. These properties help you understand how a method will behave in different situations, how to test it, and where to apply it. One of these properties is **determinism**. + +A **deterministic method** always returns the same result for the same input data. For example, the method that extracts a character from a string by its position can be called deterministic: + +```java +"wow".charAt(1); // 'o' +"wow".charAt(1); // 'o' + +"hexlet".charAt(0); // 'h' +"hexlet".charAt(0); // 'h' +``` + +No matter how many times we call `charAt()` with the argument `1` for the string `"wow"`, it always returns `'o'`. The result depends only on the input data and does not change from call to call. + +## Non-deterministic methods + +The opposite type is **non-deterministic methods**. They return different results for the same input data or when there is none (methods without arguments). A good example is the method that returns a random number: + +```java +// A method that returns a random number +Math.random(); // 0.09856613113197676 +Math.random(); // 0.8839904367241888 +``` + +This method has no arguments, but its result is different every time. How different it is does not matter. Even if just one call in a million gives another result, the method is considered non-deterministic. + +```text +Deterministic: Non-deterministic: +"wow".charAt(1) → always 'o' Math.random() → 0.42 +"wow".charAt(1) → always 'o' Math.random() → 0.91 +"wow".charAt(1) → always 'o' Math.random() → 0.07 +``` + +## Why this is important + +Determinism affects how we work with methods. + +- deterministic methods are easy to test and predict; +- they are simpler to optimize and reuse; +- non-deterministic methods are harder to check, because the result changes. + +That is why, wherever possible, it is better to aim for a method to stay deterministic. diff --git a/modules/35-methods-using/200-methods-deterministic/en/data.yml b/modules/35-methods-using/200-methods-deterministic/en/data.yml new file mode 100644 index 00000000..b9bb6a8a --- /dev/null +++ b/modules/35-methods-using/200-methods-deterministic/en/data.yml @@ -0,0 +1,10 @@ +--- +name: Determinism +tips: + - | + [Pure function](https://en.wikipedia.org/wiki/Pure_function) +definitions: + - name: Side effect + description: >- + an action that changes the external environment (the execution + environment). For example, printing to the screen or sending an email. diff --git a/modules/35-methods-using/200-methods-deterministic/es/README.md b/modules/35-methods-using/200-methods-deterministic/es/README.md index 90751796..3708d509 100644 --- a/modules/35-methods-using/200-methods-deterministic/es/README.md +++ b/modules/35-methods-using/200-methods-deterministic/es/README.md @@ -1,11 +1,20 @@ -Independientemente del lenguaje de programación utilizado, los métodos tienen algunas propiedades fundamentales. Conocer estas propiedades facilita predecir el comportamiento de los métodos, las formas de probarlos y dónde utilizarlos. Una de estas propiedades es el determinismo. Un método se considera determinista cuando, para los mismos parámetros de entrada, devuelve siempre el mismo resultado. Por ejemplo, un método que extrae un carácter de una cadena es determinista. +Los métodos, en cualquier lenguaje de programación, tienen propiedades fundamentales. Estas propiedades ayudan a entender cómo se comportará un método en distintas situaciones, cómo probarlo y dónde aplicarlo. Una de esas propiedades es el **determinismo**. + +Un **método determinista** siempre devuelve el mismo resultado con los mismos datos de entrada. Por ejemplo, se puede llamar determinista al método que extrae un carácter de una cadena por su posición: ```java "wow".charAt(1); // 'o' "wow".charAt(1); // 'o' + +"hexlet".charAt(0); // 'h' +"hexlet".charAt(0); // 'h' ``` -No importa cuántas veces llamemos a este método pasándole el valor `1`, siempre devolverá `'o'`. Por otro lado, un método que devuelve un número aleatorio no es determinista, ya que para una misma entrada (incluso si está vacía, es decir, no se aceptan parámetros) siempre obtendremos un resultado diferente. No importa cuán diferente sea, incluso si una de cada millón de llamadas devuelve algo diferente, automáticamente se considera un método no determinista. +No importa cuántas veces llamemos a `charAt()` con el argumento `1` para la cadena `"wow"`, siempre devolverá `'o'`. El resultado depende solo de los datos de entrada y no cambia de una llamada a otra. + +## Métodos no deterministas + +Al tipo opuesto pertenecen los **métodos no deterministas**. Devuelven resultados distintos con los mismos datos de entrada o cuando no los hay (métodos sin argumentos). Un buen ejemplo es el método que devuelve un número aleatorio: ```java // Método que devuelve un número aleatorio @@ -13,4 +22,21 @@ Math.random(); // 0.09856613113197676 Math.random(); // 0.8839904367241888 ``` -¿Por qué es importante saber esto? El determinismo afecta seriamente muchos aspectos. Las funciones deterministas son convenientes para trabajar, son fáciles de optimizar y de probar. Si es posible hacer que una función sea determinista, es mejor hacerlo así. +Este método no tiene argumentos, pero su resultado es diferente cada vez. Cuán diferente sea no importa. Incluso si una sola llamada entre un millón da otro resultado, el método se considera no determinista. + +```text +Determinista: No determinista: +"wow".charAt(1) → siempre 'o' Math.random() → 0.42 +"wow".charAt(1) → siempre 'o' Math.random() → 0.91 +"wow".charAt(1) → siempre 'o' Math.random() → 0.07 +``` + +## Por qué esto es importante + +El determinismo influye en cómo trabajamos con los métodos. + +- los métodos deterministas son fáciles de probar y de predecir; +- son más simples de optimizar y de reutilizar; +- los métodos no deterministas son más difíciles de comprobar, porque el resultado cambia. + +Por eso, donde sea posible, es mejor intentar que un método siga siendo determinista. diff --git a/modules/35-methods-using/200-methods-deterministic/es/data.yml b/modules/35-methods-using/200-methods-deterministic/es/data.yml index a131e02c..7b17b10e 100644 --- a/modules/35-methods-using/200-methods-deterministic/es/data.yml +++ b/modules/35-methods-using/200-methods-deterministic/es/data.yml @@ -1,6 +1,10 @@ --- name: Determinismo tips: - - > - [Funciones - deterministas](https://es.wikipedia.org/wiki/Función_pura#Determinismo_de_la_función) + - | + [Algoritmo determinista](https://es.wikipedia.org/wiki/Algoritmo_determinista) +definitions: + - name: Efecto secundario + description: >- + acción que modifica el entorno externo (el entorno de ejecución). Por + ejemplo, la salida en pantalla o el envío de un correo. diff --git a/modules/35-methods-using/300-variadic-parameters/en/EXERCISE.md b/modules/35-methods-using/300-variadic-parameters/en/EXERCISE.md new file mode 100644 index 00000000..9255166d --- /dev/null +++ b/modules/35-methods-using/300-variadic-parameters/en/EXERCISE.md @@ -0,0 +1,7 @@ +Implement the `makeSentence()` method. Inside it, using the `String.join()` method, assemble a sentence from the separate words `Java`, `is`, and `awesome`, separating them with spaces. The method must return the finished string. + +```java +App.makeSentence(); // => "Java is awesome" +``` + +The first argument passed to `String.join()` is the separator (a space), and after it comes the variable number of words to join. diff --git a/modules/35-methods-using/300-variadic-parameters/en/README.md b/modules/35-methods-using/300-variadic-parameters/en/README.md new file mode 100644 index 00000000..0aa4a843 --- /dev/null +++ b/modules/35-methods-using/300-variadic-parameters/en/README.md @@ -0,0 +1,30 @@ +Most methods take a fixed number of arguments: as many parameters as are specified in the declaration, that is how many values you need to pass. But there are methods to which you can pass any number of arguments — from zero to dozens. Such methods are called **methods with a variable number of parameters** (in English, *variadic*). + +A good example is the `String.join()` method. It joins strings with a separator, and the number of strings being joined can be any: + +```java +String.join("-", "2024", "01", "15"); // "2024-01-15" +String.join(" ", "Hello", "world"); // "Hello world" +String.join(", ", "a", "b", "c", "d"); // "a, b, c, d" +``` + +The first argument is the separator, and everything that comes after it is the variable number of strings. In the first call there are three of them, in the second — two, in the third — four. The method itself adapts to any number of arguments. + +The `String.format()` and `System.out.printf()` methods work the same way — they too can be passed a different number of arguments depending on how many values need to be substituted. + +## How it works + +When a method is declared, the variable number of parameters is written using three dots after the type: + +```java +// String... values is exactly the variable number of string arguments +public static String join(String separator, String... values) { + // here is the code that processes values +} +``` + +The notation `String...` means "zero or more strings". Required parameters (like `separator`) go first, and the variable part is always last. Inside the method, these arguments are available as an ordinary array, so you can iterate over them and do something with them. We will learn to define such methods later, but for now it is important to be able to use them. + +## Why it's needed + +A variable number of parameters makes methods flexible. There is no need to create separate methods `join2()`, `join3()`, `join4()` for each number of strings — one method is enough, which accepts any number of them. This removes duplication and simplifies working with the standard library: a huge number of its methods are designed precisely for a variable number of arguments. diff --git a/modules/35-methods-using/300-variadic-parameters/en/data.yml b/modules/35-methods-using/300-variadic-parameters/en/data.yml new file mode 100644 index 00000000..ee6b7a5f --- /dev/null +++ b/modules/35-methods-using/300-variadic-parameters/en/data.yml @@ -0,0 +1,12 @@ +--- +name: Methods with a variable number of parameters +tips: + - > + [The String.join() method in the + documentation](https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/lang/String.html) +definitions: + - name: Variable number of parameters (varargs) + description: >- + the ability of a method to accept any number of arguments of the same + type. In the declaration it is written using three dots after the type, + for example `String... values`. diff --git a/modules/35-methods-using/300-variadic-parameters/es/EXERCISE.md b/modules/35-methods-using/300-variadic-parameters/es/EXERCISE.md new file mode 100644 index 00000000..61a9aba8 --- /dev/null +++ b/modules/35-methods-using/300-variadic-parameters/es/EXERCISE.md @@ -0,0 +1,7 @@ +Implementa el método `makeSentence()`. Dentro de él, con el método `String.join()`, arma una oración a partir de las palabras separadas `Java`, `is` y `awesome`, separándolas con espacios. El método debe devolver la cadena resultante. + +```java +App.makeSentence(); // => "Java is awesome" +``` + +El primer argumento que se pasa a `String.join()` es el separador (un espacio), y después viene el número variable de palabras que hay que unir. diff --git a/modules/35-methods-using/300-variadic-parameters/es/README.md b/modules/35-methods-using/300-variadic-parameters/es/README.md new file mode 100644 index 00000000..823b24fc --- /dev/null +++ b/modules/35-methods-using/300-variadic-parameters/es/README.md @@ -0,0 +1,30 @@ +La mayoría de los métodos aceptan un número fijo de argumentos: hay que pasar tantos valores como parámetros se indiquen en la declaración. Pero hay métodos a los que se les puede pasar cualquier cantidad de argumentos, desde cero hasta decenas. Estos métodos se llaman **métodos con un número variable de parámetros** (en inglés, *variadic*). + +Un buen ejemplo es el método `String.join()`. Une cadenas con un separador, y la cantidad de cadenas que se unen puede ser cualquiera: + +```java +String.join("-", "2024", "01", "15"); // "2024-01-15" +String.join(" ", "Hola", "mundo"); // "Hola mundo" +String.join(", ", "a", "b", "c", "d"); // "a, b, c, d" +``` + +El primer argumento es el separador, y todo lo que viene después es el número variable de cadenas. En la primera llamada hay tres, en la segunda dos, en la tercera cuatro. El método se adapta por sí mismo a cualquier cantidad de argumentos. + +Los métodos `String.format()` y `System.out.printf()` funcionan de la misma manera: también se les puede pasar un número diferente de argumentos según cuántos valores haya que sustituir. + +## Cómo funciona + +Cuando se declara un método, el número variable de parámetros se escribe con tres puntos después del tipo: + +```java +// String... values es justamente el número variable de argumentos de cadena +public static String join(String separator, String... values) { + // aquí va el código que procesa values +} +``` + +La notación `String...` significa "cero o más cadenas". Los parámetros obligatorios (como `separator`) van primero, y la parte variable siempre va al final. Dentro del método, estos argumentos están disponibles como un array normal, por lo que se puede recorrerlos y hacer algo con ellos. Aprenderemos a definir estos métodos más adelante, pero por ahora es importante saber usarlos. + +## Para qué sirve + +El número variable de parámetros hace que los métodos sean flexibles. No hay que crear métodos separados `join2()`, `join3()`, `join4()` para cada cantidad de cadenas: basta con un solo método que acepte cualquier cantidad de ellas. Esto elimina la duplicación y simplifica el trabajo con la biblioteca estándar: una enorme cantidad de sus métodos está diseñada precisamente para un número variable de argumentos. diff --git a/modules/35-methods-using/300-variadic-parameters/es/data.yml b/modules/35-methods-using/300-variadic-parameters/es/data.yml new file mode 100644 index 00000000..80ebc201 --- /dev/null +++ b/modules/35-methods-using/300-variadic-parameters/es/data.yml @@ -0,0 +1,12 @@ +--- +name: Métodos con un número variable de parámetros +tips: + - > + [El método String.join() en la + documentación](https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/lang/String.html) +definitions: + - name: Número variable de parámetros (varargs) + description: >- + la capacidad de un método de aceptar cualquier cantidad de argumentos del + mismo tipo. En la declaración se escribe con tres puntos después del tipo, + por ejemplo `String... values`. diff --git a/modules/35-methods-using/400-stdlib/en/EXERCISE.md b/modules/35-methods-using/400-stdlib/en/EXERCISE.md new file mode 100644 index 00000000..c660594d --- /dev/null +++ b/modules/35-methods-using/400-stdlib/en/EXERCISE.md @@ -0,0 +1,12 @@ + +Let's write code in the "repeat after the teacher" style. Let's calculate the number of days between two dates using Java's built-in capabilities. Try to "play" with the dates. + +```java +// From date +LocalDate dateFrom = LocalDate.of(2017, Month.MAY, 24); +// To date +LocalDate dateTo = LocalDate.of(2017, Month.JULY, 29); +// Number of days between these dates +long noOfDaysBetween = ChronoUnit.DAYS.between(dateFrom, dateTo); +System.out.println(noOfDaysBetween); +``` diff --git a/modules/35-methods-using/400-stdlib/en/README.md b/modules/35-methods-using/400-stdlib/en/README.md new file mode 100644 index 00000000..f9a2fe75 --- /dev/null +++ b/modules/35-methods-using/400-stdlib/en/README.md @@ -0,0 +1,9 @@ +Java, like any other language, comes with a set of useful methods. All together they make up the so-called **standard library**. It usually includes thousands of methods that are impossible to memorize — and there is no need to. It is assumed that any programmer knows where to look for their documentation and has a rough idea of what they want to achieve. And after that, it is a matter of technique. If you take the internet away from programmers, most of them will not be able to program anything. + +For beginners, this information often looks like: "Go somewhere, I don't know where, bring back something, I don't know what". That is, it is unclear how to learn about these methods when you know nothing at all. Strangely enough, there is no way to learn once and for all everything you need to know. Every developer, in the process of their professional growth, gets acquainted with more and more interesting methods that solve their problems more elegantly, and thus expands their arsenal. + +Here are some tips on how to learn about new methods: + +* Always clearly track which data type you are currently working with. Almost always you will find the needed method in the corresponding section of the documentation — for example, to work with strings you need to study string methods +* Periodically open the section with standard methods for the topic you are studying and simply skim through them, studying signatures and ways of use +* Read other people's code more often, especially the code of the libraries you use. It is all available on GitHub diff --git a/modules/35-methods-using/400-stdlib/en/data.yml b/modules/35-methods-using/400-stdlib/en/data.yml new file mode 100644 index 00000000..0a7f717e --- /dev/null +++ b/modules/35-methods-using/400-stdlib/en/data.yml @@ -0,0 +1,5 @@ +--- +name: Standard library +tips: + - | + [How to search for technical information](https://guides.hexlet.io/how-to-search/) diff --git a/modules/35-methods-using/500-methods-variants/en/EXERCISE.md b/modules/35-methods-using/500-methods-variants/en/EXERCISE.md new file mode 100644 index 00000000..f3a91cac --- /dev/null +++ b/modules/35-methods-using/500-methods-variants/en/EXERCISE.md @@ -0,0 +1,7 @@ + +The variable `emoji` contains a sad text emoticon *-(*. Your task is to make this emoticon happy using two transformations: + + * Add eyes on the left *:* + * Replace *(* with *)* (using the string method `replace()`) + +You should get: *:-)*. Print it to the screen. diff --git a/modules/35-methods-using/500-methods-variants/en/README.md b/modules/35-methods-using/500-methods-variants/en/README.md new file mode 100644 index 00000000..522c6ec4 --- /dev/null +++ b/modules/35-methods-using/500-methods-variants/en/README.md @@ -0,0 +1,73 @@ +One of the fundamental topics in Java, on which code is built, is classes and objects. They appear literally from the first lines of code, but learning them and starting to use them is not quite simple. That is why the study of objects and classes is stretched over many lessons. In this lesson, we will dive a little more into how the language works. Don't worry if the puzzle still doesn't come together — that's normal. Classes, objects, and methods are a complex topic that takes time. + +We have already encountered methods built into Java in different forms: + +```java +System.out.println(); +varname.toLowerCase(); +varname.substring(); +Integer.parseInt(); +ChronoUnit.DAYS.between(); +``` + +All such calls can be divided into two groups: + +1. Calls of methods on objects, such as strings +2. Calls of static methods that are not tied to specific objects + +## Calls of methods on objects + +So far we have encountered only strings among objects, but the principle is the same for any objects: + +```java +// Syntax for creating an object +// new - creates a new object of the class +var user = new User(); + +// Gets the user's name +user.getName(); + +// Example with other objects + +// Gets the current day +currentDate.getDayOfMonth(); +// Checks that the file exists +file.exists(); +``` + +Such methods perform actions on the objects on which they are called, and often do not take any arguments. For simplicity, objects can be thought of as data that is available inside the method. For example, the string method `toLowerCase()` takes the original string inside itself, transforms it, and returns the result outward. + +By the way, `System.out.println()` is a method of the `out` object, which lies inside the `System` class. + +## Calls of static methods + +But not all method calls are tied to objects: sometimes there is an action, but there is no object. In such cases, **static methods** are used. + +What can this be? Mathematical operations on numbers or some actions that do not relate to a specific object, but relate to all objects of a given type. In this case, the method almost always relies on data that comes in the form of parameters: + +```java +// Getting a random number, called directly from the Math class +Math.random(); + +// Reading data at the specified path +Files.readString(path); +``` + +The `Math` and `Files` classes in this case are needed only for the call, because the methods are defined inside them. Java does not allow defining methods outside of classes. + +To be honest, it's not all that simple. You can always come up with some object over which the computation happens. The reverse is also true: you can always do without objects. There are languages in which there are no objects at all. In the end, everything is decided by whoever designs the specific part of the code: + +```java +// Without an object, a static method +Files.readString(path); + +// Although it could also be done through a file object +path.read(); +``` + +## Conclusions + +* Static methods are not tied to specific objects and are called directly from the class +* Non-static methods build their logic relative to the data of the object itself and are called on specific objects + +All this smoothly leads us to the possibility of creating classes, objects, and methods on our own, without which it is impossible to imagine any program, even a small one. diff --git a/modules/35-methods-using/500-methods-variants/en/data.yml b/modules/35-methods-using/500-methods-variants/en/data.yml new file mode 100644 index 00000000..d85693b1 --- /dev/null +++ b/modules/35-methods-using/500-methods-variants/en/data.yml @@ -0,0 +1,2 @@ +--- +name: Kinds of methods diff --git a/modules/35-methods-using/description.en.yml b/modules/35-methods-using/description.en.yml new file mode 100644 index 00000000..d2f5178c --- /dev/null +++ b/modules/35-methods-using/description.en.yml @@ -0,0 +1,5 @@ +--- + +name: Calling methods +description: | + To express any arbitrary operation in programming, there is the concept of a "function". Functions are the building blocks that programmers use to build systems. In Java, functions are called methods. In this module, we will learn how to use methods that already exist. We will look at the method signature in the documentation and figure out how to use it.