Класс String. Метод regionMatches

В классе String есть булевский метод regionMatches, который сравнивает
подстроку одной строки с подстрокой другой строки.
Метод используется достаточно редко(я на практике использовал только один раз), но
данный метод достаточно интересен.

Есть целых два таких метода.

Первый — зависит от регистра, второй — нет.

Зависит от регистра

 public boolean regionMatches(int toffset, String other, int ooffset, int len)

toffset — с этой позиции мы начинаем отсчет для строки 1.
other — другая строка
ooffset — позиция для другой строки
len — количество символов, которые мы сравниваем.

Пример:

String a = "Мама мыла раму";
String b = "А раму мыла мама";
		 	
System.out.println(a.regionMatches(10, b, 2, 4));

Есть две строки.
Для первой строки мы отсчитываем 10 позиций и берем 4 символа, для второй строки берем 4 символа со второй позиции.
Т.е. получается, что мы сравниваем слова «раму» с первой и второй строки — строки равны между собой, значит результат
true.

Метод

public boolean regionMatches(boolean ignoreCase, int toffset, String other, int ooffset, int len) 

Точно такой же, только здесь есть пареметр ignoreCase, который позволяет игнорировать регистр.

Реклама

Java8 Перебор map

Когда-то давно была мини статья по перебору Map
https://user12vv.wordpress.com/2013/10/30/java-%d1%81%d0%bf%d0%be%d1%81%d0%be%d0%b1%d1%8b-%d0%bf%d0%b5%d1%80%d0%b5%d0%b1%d0%be%d1%80%d0%b0-%d0%ba%d0%be%d0%bb%d0%bb%d0%b5%d0%ba%d1%86%d0%b8%d0%b8-map/

В Java8 все гораздо проще и без всяких циклов:

Map<String, Integer> fruits = new HashMap<>();
 	
fruits.put("pineapple", 100);
fruits.put("banana", 15);
fruits.put("mango", 60);
fruits.put("papaya", 20);
fruits.put("orange", 25);
fruits.put("lemon", 7);

fruits.forEach((key, value) -> {
		System.out.println(key + " == " + value);
});

Метод, который возвращает stream

Для удобства работы с коллекциями используются стримы.
Можно сделать весьма неплохой метод который будет возвращать стрим

Обычный POJO-класс с конструктором, геттерами и сеттерами

public class Person {
	private String name;
    private Integer age;

    Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public Integer getAge() {
		return age;
	}

	public void setAge(Integer age) {
		this.age = age;
	}

	@Override
	public String toString() {
		return "Person [name=" + name + ", age=" + age + "]";
	}

}

Класс для собирания данных в коллекцию.
Метод getAllPersons собирает данные в коллекцию List. Данные могут храниться где угодно: БД, Excel, в самом коде.

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.function.Predicate;
import java.util.stream.Stream;

public class PersonCollect {
	
	private List<Person> persons = new ArrayList<>();

	public Stream<Person> persons() {
		return getAllPersons().stream();
	}
		
	public List<Person> getAllPersons() {
		if (persons.isEmpty()) {
			persons = Arrays.asList(new Person("Andrew", 17), new Person("Igor", 23),
					new Person("Ira", 23), new Person("Maxim", 24));
		}
		return persons;
	}

}

Неплохая идея, сделать метод persons(), который будет возвращать стрим, т.е. если мы захотим как-то модифицировать коллекцию, то
будем писать меньше кода.

Соответственно, если надо вывести только людей старше 20 лет, то код будет таким:

		 PersonCollect p = new PersonCollect();
		 List<Person> older20 = p.persons().filter(x->x.getAge()>20).collect(Collectors.toList());
		 System.out.println(older20);

Java8 чтение данных из файла

У класса Files есть метод lines, который читает данные из файла.

public static Stream<String> lines(Path path) throws IOException {
        return lines(path, StandardCharsets.UTF_8);
    }

Что здорово, там по дефолу проставляется кодировка UTF_8, т.е. нам её не надо указывать явно.

Т.е. это стрим, то мы можем сделать метод, который данные из каждой строки файла складывает в коллекцию лист.
Тут можно сделать в filter например игнорирование комментариев(считаем, что # это комментарий), удалять дублирующиеся символы
distinct и еще много чего:

public static List<String> listLineFiles(String pathToFile) {
		
		try {
			return  Files.lines(Paths.get(pathToFile)).filter(x->!x.startsWith("#")).distinct().collect(Collectors.toList());
		} catch (IOException e) {
			return null;
		}
	}

Т.е. есть файл с данными
example.org
example2.org
example3.org
example3.org
#для презентаций новым клиентам
exampledemo.org

Если мы вызовем данный метод, передав туда путь к файлу, то в коллекции будут только:
[example.org, example2.org, example3.org, exampledemo.org]

Java8 Метод removeIf для коллекций

В Java8 появился метод removeIf
Т.е. у вас есть некая коллекция элементов и вам надо из этой коллекции удалить данные.
До Java8 использовались Iterator, что было достаточно громоздко и сложно.
Но сейчас же это можно сделать просто в одну строчку

List<String> cities  = new ArrayList<>(Arrays.asList("Minsk", "Moscow" , "Kiev", "Ljubljana"));
	
cities.removeIf(x -> x.length()>7 && x.startsWith("L"));
	
System.out.println(cities);

На консоль НЕ будут выведены те города, длина которых больше 7 символов и который начинаются с буквы L.
Т.е. в данном случае:

[Minsk, Moscow, Kiev]
Метод removeIf он на вход принимает Предикат, т.е.на вход м.б. любое значение, но возвращаться будет тип boolean

Стоит также отметить, что мы модифицируем существующий список, а не возвращаем новый.

Java8. Основы StreamAPI

Лямбды появились в Java8 уже давно, но активно их использовать начал только сейчас.
Задача, найти четные числа от 5 до 50:

List<Integer> l = Arrays.asList(1,4,2,-30, 6, 45, 50,50, 20);
l  = l.stream().filter(s->s%2 == 0 && s>5 && s<=50).collect(Collectors.toList());
System.out.println(l);

Вывод на консоль:
[6, 50, 50, 20]

Найти количество четных чисел от 5 до 50:

List<Integer> l = Arrays.asList(1,4,2,-30, 6, 45, 50,50, 20);
long count  = l.stream().filter(s->s%2 == 0 && s>5 && s<=50).count();
System.out.println(count);

Вывод на консоль:4

Найти количество четных чисел от 5 до 50 исключая дубликаты(distinct):

List<Integer> l = Arrays.asList(1,4,2,-30, 6, 45, 50,50, 20);
long count  = l.stream().filter(s->s%2 == 0 && s>5 && s<=50).distinct().count();
System.out.println(count);

Вывод на консоль:3

enum ChronoUnit. Метод between

У enum ChronoUnit есть метод between, который позволяет находить время между двумя временными промежутками.
Например, сколько минут между временем 15:30 и 16:25

LocalTime t1 = LocalTime.of(15, 30);
LocalTime t2 = LocalTime.of(16, 25);
		
long l = ChronoUnit.MINUTES.between(t1, t2);
System.out.println(l);

Вывод на консоль — 55

Аналогично, можно искать часы, дни и т.п

Java. List методы indexOf и lastIndexOf

Все прекрасно знают методы indexOf и lastIndexOf для String, которые возвращают индекс первого и последнего
вхождения элемента в строку. Нумерация идет с 0, если ничего не найдено — то возвращается -1

String s = "Мама мыла раму";
//1	
System.out.println(s.indexOf("а"));
//11
System.out.println(s.lastIndexOf("а"));

Но аналогичные методы есть и для коллекции List, что еще больше упрощает код:

List<String> cities = new ArrayList<>(Arrays.asList("Minsk", "Moscow", "Brest", "Minsk"));
//0	
System.out.println(cities.indexOf("Minsk"));
//-1, т.к. Paris нет в коллекции
System.out.println(cities.indexOf("Paris"));
//3
System.out.println(cities.lastIndexOf("Minsk"));

Java8. List — метод replaceAll

В Java8 добавили весьма неплохой метод replaceAll, который изменяет все элементы коллекции.

Пример, есть некая коллекция и мы хотим у всех элементов убрать начальные и конечные пробелы.
Раньше мы делали так:

List<String> list = new ArrayList<>(Arrays.asList(" Minsk", "Moscow      ", "   Brest   "));

		
for (int i = 0; i < list.size(); i++)
  list.set(i, list.get(i).trim());

Но с выходом Java8 это можно сделать в одну(!!!) строчку без всяких циклов:

list.replaceAll(String::trim);

Вывод на консоль:
[Minsk, Moscow, Brest]

Java Работа с коллекциями объектов

Нам всегда приходится работать с объектами, которые собираются в коллекцию.

Пример, есть обычный класс Product

package org.example.pojo;

public class Product {
	
	private String name = "";
	private String price = "";
	private String brand = "";
	
	
	public String getName() {
		return name;
	}
	public Product setName(String name) {
		this.name = name;
		return this;
	}
	public String getPrice() {
		return price;
	}
	public Product setPrice(String price) {
		this.price = price;
		return this;
	}
	public String getBrand() {
		return brand;
	}
	public Product setBrand(String brand) {
		this.brand = brand;
		return this;
	}
	
	
	@Override
	public String toString() {
		return "AllProduct [name=" + name + ", price=" + price + ", brand=" + brand + "]";
	}
}

Мы видим обычный POJO-класс с измененными сеттерами. Плюс этого класса, что здесь приватные поля с геттерами/сеттарами.
Нам необходимо только знать, какие должны быть поля, все остальное IDE генерит сама.

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

package org.example.pojoCollections;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;

import org.apache.log4j.Logger;
import org.example.pojo.Product;

public class ProductCollections {
	
	private static final Logger log = Logger.getLogger(ProductCollections.class);
	
	public static ArrayList<Product> prod = new ArrayList<>();

	public int size() {
		return prod.size();
	}

	public static ArrayList<Product>  getAllProduct() {
		ArrayList<Product> products = prod;
		if (prod.isEmpty()) {
			Product pr1 = new Product().setName("Икра красная \"Вкуснота \"").setBrand("Белорусская традиция").setPrice("120");
			Product pr2 = new Product().setName("Чай зеленый \"Принцесса Нури\"").setBrand("Ахмад").setPrice("15");		
			Product pr3 = new Product().setName("Чай ароматный с бергамотом.").setBrand("Беседа").setPrice("221");
			Product pr4 = new Product().setName("Lipton Yellow Label").setBrand("Lipton").setPrice("24");
			Product pr5 = new Product().setName("Magic aroma").setBrand("Lipton").setPrice("18");
			Product pr6 = new Product().setName("English Breakfast").setBrand("Lipton").setPrice("12");
			Product pr7 = new Product().setName("Royal Ceylon").setBrand("Lipton").setPrice("14");
		
		
				
			
			products.add(pr1);
			products.add(pr2);
			products.add(pr3);
			products.add(pr4);
			products.add(pr5);
			products.add(pr6);
			products.add(pr7);
		
		}
		return products;
	}

	public void printAll(ArrayList<Product> prod) {
		for (int i = 0; i < size(); i++) {
			log.info(prod.get(i));
		}
	}

	@Override
	public String toString() {
		for (int i = 0; i < size(); i++) {
			log.info(prod.get(i));
		}
		return "";
	}

	public ArrayList<Product> getProd() {
		return prod;
	}

	public void setProd(ArrayList<Product> prod) {
		this.prod = prod;
	}

	public ArrayList<Product> sortByName() {
		Collections.sort(getAllProduct(), sortByName);
		return prod;
	}

	public ArrayList<Product> sortByPrice(ArrayList<Product> prod) {
		Collections.sort(prod, sortByPrice);
		return prod;

	}

	public Product prodWithMaxPrice() {
		return Collections.max(getAllProduct(), sortByPrice );
	}

	public Product prodWithMinPrice() {
		return Collections.min(getAllProduct(), sortByPrice );
	}

	public ArrayList<Product> findByName(String productName) {

		ArrayList<Product> productWithEqualsName = new ArrayList<>();
		for (int i = 0; i < size(); i++) {
			if (prod.get(i).getName().equalsIgnoreCase(productName)) {
				productWithEqualsName.add(getAllProduct().get(i));
			}
		}

		if (productWithEqualsName.isEmpty()) {
			log.info("Didnt find elemets with product name \"" + productName + "\".");
		}
		return productWithEqualsName;
	}

	private  Comparator<Product> sortByName = new Comparator<Product>() {

		@Override
		public int compare(Product p1, Product p2) {
			return p1.getName().compareTo(p2.getName());
		}
	};

	private  Comparator<Product> sortByPrice = new Comparator<Product>() {

		@Override
		public int compare(Product p1, Product p2) {
			return Integer.parseInt(p1.getPrice()) - Integer.parseInt(p2.getPrice());
		}
	};
}


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

package org.example.main;

import org.apache.log4j.Logger;
import org.example.pojoCollections.ProductCollections;

public class MainClass {
	
	private static final Logger log = Logger.getLogger(MainClass.class);
	
	public static void main(String[] args) {
		ProductCollections cP = new ProductCollections();
		log.info("Max price is = " + cP.prodWithMaxPrice().getPrice());
		log.info("Size is " + cP.size());
		log.info("Min price is = " + cP.prodWithMinPrice().getPrice());
		log.info(cP.findByName("Milk 4"));
		log.info(cP.sortByName());		
	}

}


Весь код можно найти на гитхаб —

https://github.com/VictorSem/Product