Regular expression

import java.util.regex.*;
class RegTest{
public static void maint(String[]  args){
  Pattern p = new Pattern("ab");        // регулярное выражание
  Matcher m = p.matcher("abaaaba");  // текст
  while(m.find()){
    System.out.print(m.start() + " ");  // вывод: 0 4
  }
}
Примеры основных метасимволов:
  ^     - (крышка, цирркумфлекс) начало проверяемой строки
  $     - (доллар) конец проверяемой строки
  .     - (точка) представляет собой сокращенную форму записи для символьного класса, совпадающего с любым символом
  |     -  означает «или». Подвыражения, объединенные этим способом, называются альтернативами (alternatives)
  ?     - (знак вопроса) означает, что предшествующий ему символ является необязательным
  +     -  обозначает «один или несколько экземпляров непосредственно предшествующего элемента
  *     –  любое количество экземпляров элемента (в том числе и нулевое)
  \\d   –  цифровой символ
  \\D   –  не цифровой символ
  \\s   –  пробельный символ
  \\S   –  не пробельный символ
  \\w   –  буквенный или цифровой символ или знак подчёркивания
  \\W   –  любой символ, кроме буквенного или цифрового символа или знака подчёркивания

 Class Matcher
 boolean matches() просто указывает, соответствует ли вся входная последовательность шаблону.
 int start() указывает значение индекса в строке, где начинается соответствующая шаблону строка.
 int end() указывает значение индекса в строке, где заканчивается соответствующая шаблону строка плюс единица.
 String group() - возвращает найденную строку

 String group(int group) - если у Вас в регулярном выражении были группы, то можно вывести только кусочек строки соответствующей определенной группе.

Квантификаторы

+     - Одно или более (greed)
    - Ноль или более (greed)
?     - Ноль или одно (greed)
{n}   - Ровно n раз
{m,n} - От m до n включительно
{m,}  - Не менее m
{,n}  - Не более n

Теперь мы можем полностью понять регулярное выражение с самого первого примера: "^[a-z0-9_-]{3,15}$" .
Разберем её по кусочкам:
^ - начало строки
[a-z0-9_-] - символ который может быть маленькой латинской буквой или цифрой или символом подчеркивания.
{3,15} - предыдущий объект может повторяться от 3х до 15раз.

Serialization

class Cat implement Serializable {}
public class Test {
public static void main(String[] args){
   Cat cat = new Cat();
   try{
        FileOutputStream fos = new FileOutputStream("file1.ser");
        ObjectOutputStream oos = new ObjectOutputStream(fos);
        oos.writeObject(cat);
        oos.close();

        FileInputStream fis = new FileInputStream("file2.ser");
        ObjectInputStream ois = new ObjectInoutStream(fis);
        cat = (Cat)  ois.readObject();
        ois.close();
        }
catch(Exception e) {}
       }
}
При десереализации конструктор не вызывается (но конструторы супер-классов вызываются если они не сереализированы). При сереализации коллекции или массива должны быть сереализованы все их элементы.
Static не сереализируется, всегда по дефолту.

Input / Output

File - абстракционное представление файла.
FileReader -класс, который используется для низкоуровневого (посимвольно) чтения с файла. Обычно обвертуется высокоуровневыми классами типа BufferedReader.
File f = new File("file.txt");
boolean newFile = f.createNewFile();
FileWriter - как FileReader, только для записи. Класс-обвертка - BufferdWriter.
try{
FileWriter fw = new FileWriter(f);
fs.write("abc");
fw.flush(); - гарантия что весь поток успел записатся в файл.
fs.close();
char[] charArray = new char[50];
FileReader fr = new FileReader(f);
int size = fr.read(charArray);
fr.close();
}
catch(IOException e) {
}
BufferedReader - на отмену от FileReader cчитывает сразу все данные с файла и хранит их в буфере. Есть дополнительніе методы, например, readLine.

BufferedReader br = new BufferedReader(fr);
String data = br.readLine();

BufferdWriter - на отмену от FileWriter записывает все данные при одном обращении к файлу.

String

String - immutable!!!!!!!!!!!!!!!!!!

String s =  "abc";  - помещает строку в пул. Можно применять оператор "==".

s = s.concat(" sda"); - помещает в пул еще две строки " sda" и "abc sda" (если s.concat(" sda")  s.replace('a', 'x') без присвоения, то новая строка потеряется в пуле).

String s = new String("abc"); - создает новую строку (обьект в не в пуле, а в обычном хипе. Но к этом еще появляется "abc" в пуле). Не использовать так как создается лишний обьект. Оператор "==" будет давать false.

StringBuilder - потоко незащищенный. (equals и hasCode не перезаписан)
StringBuffer - потоко защищенный. (equals и hasCode не перезаписан)
Используются, когда нужна делать много изменений в строке, чтобы не перегружать пул.

System.out.println(a + b + "sss" + a + b); // 10sss55
System.out.println((a + b) + "sss" + (a + b)); 10sss10/
public class Test138 
{ 
    public static void stringReplace (String text) 
    {
        text = text.replace ('j' , 'c'); /* Line 5 */
 //этот метод не сработает так String immutable ( "работает как примитив, а не по ссылке")   
} 
    public static void bufferReplace (StringBuffer text) 
    { 
        text = text.append ("c");  /* Line 9 */
    } 
    public static void main (String args[]) 
    { 
        String textString = new String ("java"); 
        StringBuffer textBuffer = new StringBuffer ("java"); /* Line 14 */
        stringReplace(textString); 
        bufferReplace(textBuffer); 
        System.out.println (textString + textBuffer);
//выведет javajavac 
    } 
}
String a = "newspaper";
a = a.substring(5,7);
char b = a.charAt(1);
a = a + b;
System.out.println(a); //app
public class Main {     
    public static void main(String[] args) { 
        String strA = "text"; 
        String strB = "text"; 
        strA += "1"; 
        strB += "1"; 
        System.out.println(strA == strB); 
        strA = "text1"; 
        strB = "text1"; 
        System.out.println(strA == strB); 
    } 
} //false true. При конкатенации строк создается strA = new StringBuilder().append(strA).append("1").toString(); Поэтому == никогда не будет работать! 

Assertion

Assertion применяется для отловки багов, можно включать или отключать. Не должно влиять на код.
assert true;  - ничего не выведет
assert false; - выведет assertion error
assert (x == 1);
assert (x == 1) : returnFunc(); - функция не может быть void.  Функция срабатывает в случае если первое выражение false. Используется для объяснения ошибки, обычно используется String. assert (x == 1) : "Not == 1"; Exception in thread "main" java.lang.AssertionError: Not ==1
Для включения: java –enableassertions MyClass или java –ea MyClass
Для выключения применяется da или -disableassertions.

public class Test 
{ 
    public void foo() 
    {
        assert false; /* Line 5 */
        assert false; /* Line 6 */
    } 
    public void bar()
    {
        while(true)
        {
            assert false; /* Line 12 */
        } 
        assert false;  /* Line 14 */
    } 
}
Будет compilation errror, из-за того что Line 14 unreachble. Должен быть break в while

Exception

Switch оператор

switch(ВыражениеДляСравнения) {
    case Совпадение1: 
     команда;
  break;
 case Совпадение2: 
     команда;
  break;
 case Совпадение3: 
     команда;
  break;
 default: 
     оператор;
     break;
}
  • Оператор switch отличается от оператора if тем, что может выполнять проверку только равенства, а оператор if может вычислять результат булева выражения любого типа.
  • Две константы case в одном и том же операторе switch не могут иметь одинаковые значения
  • Если не использовать break, тогда будет выводить все кейсы по порядку. В default break можно не писать.
  • В switch выражениях можно использовать только byte, char, short, int (обвертки также) или enum. Но в case можно использовать только примитивы byte, char, short, int, помечены как FINAL. В java 7, можно еще использовать STRING!!!
  • case аргумент должен быть final и инициализирован.

  • default (если нету совпадений) может находится где угодно.
 case 0, 1: j = 1; //ошибка компиляции. Case может иметь только один аргумент.

instanceof

Оператор для проверки приципа IS-A.
interface Domestic {}
class Animal {}
class Dog extends Animal implements Domestic {}
class Cat extends Animal implements Domestic {}
Imagine a dog object, created with Object dog = new Dog(), then:
dog instanceof Domestic // true - Dog implements Domestic
dog instanceof Animal   // true - Dog extends Animal
dog instanceof Dog      // true - Dog is Dog
dog instanceof Object   // true - Object is the parent type of all objects
However,
animal instanceof Dog // false
null instanceof Dog // false
And,
dog instanceof Cat // does not even compile!

Альфа методы

Object методы:


  1. void finalize - вызывается сборщиком муссора один раз перед удалением обьекта.
  2. PUBLIC String toString - применяется, когда нужно узнать какуе-то информацию об обьекте. Если не переопределать, то выведет имя класса и хеш код обьекта в 16 системе.Репрезентация обьекта в текстовом формате.
  3. PUBLIC int hashCode - применяеться для коллекций Hashtable, HashMap, HasSet.
  4. PUBLIC boolean equals(Object obj) - проверяет два обьекта на равность, если не переопределен, то работает почти как == (null pointer)
  5. final void notify() - пробуждает поток, который ждет лока
  6. final void notifyAll() - пробуждает все потоки.
  7. final void wait() - заставляет текущий поток ждать, пока другой поток не вызвет notify или notifyAll.
  8. public final native Class getClass()
  9. protected native Object clone() throws CloneNotSupportedException



Wrappers (классы оболочки)

Boolean Byte  Short Integer Long  Double  (+ String)
Character  ( аргументы конструкторa: только char)
Float ( + double или String)
Используются в основном для коллекций.
Основные методы:

  1. Xxx.valueOf("011001", 2) - статический, перевод в разные системы исчисления, возвращает обвертку.
  2. .XxxValue() -  достает примитив с обвертки (int x = i2.integerValue()).
  3. Xxx.parseXxx() - статический, как valueOf только возвращает примитив.
public class WrapTest 
{
    public static void main(String [] args) 
    {
        int result = 0;
        short s = 42;
        Long x = new Long("42");
        Long y = new Long(42);
        Short z = new Short("42");
        Short x2 = new Short(s);
        Integer y2 = new Integer("42");
        Integer z2 = new Integer(42);

        if (x == y) /* Line 13 */
            result = 1;
        if (x.equals(y) ) /* Line 15 */
            result = result + 10;
        if (x.equals(z) ) /* Line 17 */
            result = result + 100;
        if (x.equals(x2) ) /* Line 19 */
            result = result + 1000;
        if (x.equals(z2) ) /* Line 21 */
            result = result + 10000;

        System.out.println("result = " + result);
    }
}
Line 13 fails because == compares reference values, not object values. Line 15 succeeds because both String and primitive wrapper constructors resolve to the same value (except for the Character wrapper). Lines 17, 19, and 21 fail because the equals() method fails if the object classes being compared are different and not in the same tree hierarchy.

public static void main (String args [])
    {
        Integer x = 127; //>128 FALSE  new Integer(127) FALSE TOO
        Integer y = 127;
        Character x1 = 'x';
        Character y1 = 'x';
Double d1 = 10d; 
Double d2 = 10d; d1==d2; //FALSE
        System.out.println(x ==  y); //true
        System.out.println(x1 ==  y1); //true
    }

Блоки инициализации

Статический блок - инициализируется при загрузке класса. Запускается только ОДИН РАЗ.
Нестатический блок - инициализируется при каждом новом создании экземпляпа класса в порядке появления. Запускается после того как конструтор выполнит super(). Если конструктор не выполняется, то и БЛОК НЕ ЗАПУСКАЕТСЯ.

abstract class Animal { 
    static { 
        System.out.println("Inside Animal"); 
    } 
} 
 
class Cat extends Animal { 
    static { 
        System.out.println("Inside Cat"); 
    } 
} 
 
class Dog extends Animal { 
    static { 
        System.out.println("Inside Dog"); 
    } 
} 
 
public class Main { 
     public static void main(String[] args){ 
          Animal cat = new Cat(); 
          Animal dog = new Dog(); 
     } 
}
public class Tasks { 
    public static Tasks instance = new Tasks(); 
    private static final int DELTA = 5; 
    private static int BASE = 7; 
    private int x; 
 
    public Tasks() { 
        x = BASE + DELTA; 
    } 
    public static int getBASE() { 
        return BASE; 
    } 
    public static void main(String[] args) { 
        System.out.println(Tasks.instance.x); 
    } 
} 
Пояснение: Инициализация статических полей осуществляется в том порядке, в котором они записаны.
В этом примере первым будет проинициализировано поле instance, а уже затем - BASE. Поэтому в момент вызова конструктора Tasks() полеBASE ещё содержит 0.
Поле DELTA является переменной-константой, поэтому компилятор сразу подставляет в выражение вместо DELTA его значение.
В итоге получаем: x = 0 + 5;

Stack & heap

Stack (стек)
Память в RAM, хранит локальные переменные.
Heap(куча)
Хранит обьекты и поля экземпляра.

Область видимости переменных


  1. Статические переменные живут дольше всего. Инициализируются при загрузке класса. И остаются до тех пор пока класс загружен в JVM.
  2. Переменные экземпляра живут до тех пока живет обьект.
  3. Локальные переменные живут до тех пор пока выполняется метод (находится в стеке памяти).
  4. Блочные переменные (самые короткоживучие) живут только пока выполняется блок.

Override & overload

Override (перезапись метода в субклассах):

  1. модификатор доступа перезаписанного метода не может быть строже.
  2. private, final, static методы не могут быть перезаписаны.
  3. нельзя расширать Exception, только УМЕНЬШАТЬ ИЛИ ВООБЩЕ УБИРАТЬ (дети exception) при перезаписи.
  4. нельзя добавлять или убирать полнустью Exception.
  5. нельзя изменять return тип.
  6. JVM сначала смотрит по ссылке, потом ищет перегруженный метод. Пример: Animal hs = new Horse(); hs.eat(). Вызовется метод с обьекта Horse. 
  7. Статические методы нельзя перезаписать, только переназначить (будут использоваться по ссылке).

Overload (перегрузка методов):

  1. должны изменять список аргументов.
  2. могут изменять тип return, модификатор доступа, изменять или создавать Exception.
  3. может быть перегружен в одно и том же классе или субклассе.
  4. тип ссылки определяет какой перегруженный метод будет вызван.

Приоритет перегруженных методов:


  1. Расширение типов ( void func(int x),  void func(long x) )
  2. Автобоксинг ( void func(Intger x), void func(Long x) ) Не действует расширения для типов оболочок. При аргументе ф-ции Long или byte нельзя кинуть Integer (IS-A FAIL).
  3. Аргумент переменной длины ( void func(int ... x) ) 
public class Clazz { 
    private void process(String... s) { 
        System.out.print("*"); 
    } 
    private void process(String s) { 
        System.out.print("1"); 
    } 
    private void process(String s, String a) { 
        System.out.print("2"); 
    } 
    public static void main(String[] args) { 
        Clazz c = new Clazz(); 
        c.process("asd"); 
        c.process("asd","asd"); 
        c.process("asd","asd","asd"); 
    } 
} //12*

public class TypesTutorial { 
 
    public static void main(String... atgs) { 
        A alpha = new B(); 
    } 
} 
 
class A { 
    A(){ 
        System.out.print("A"); 
        a(); 
    } 
     
    void a() { 
        System.out.print("a"); 
    } 
} 
 
class B extends A { 
    B() { 
        System.out.print("B"); 
        a(); 
    } 
     
    void a() { 
        System.out.print("b"); 
    } 
} // AbBb


public class Z { 
    public void print( Object o ) { 
        System.out.println( "Object" ); 
    } 
 
    public void print( String str ) { 
        System.out.println( "String" ); 
    } 
 
    public void print( Integer i ) { 
        System.out.println( "Integer" ); 
    } 
   
    public static void main(String[] args) { 
        Z z = new Z(); 
        z.print( null ); 
    } 
}  //Будет ошибка компиляции. Чтобы не было, нужно убрать метод с String или Integer или явно указать ссылку. При этом будет выведено Integer или String cответственно. Можно так же явно указывать ссылку, тогда ошибки также не будет.
class A { 
    public void m(Number n) { 
        n = 5 / 3; 
        System.out.println("class A, method m : " + n); 
    } 
} 
 
class B extends A { 
    public void m(Double d) { 
        d = d / 3; 
        System.out.println("class B, method m : " + d); 
    } 
} 
 
public class MainClass { 
    public static void main(String args[]) { 
        A a = new B(); 
        a.m(5.0); 
    } 
} //Пояснение: полиморфного вызова методов не происходит, поскольку сигнатуры void m(Number n) и void m(Double d) отличаются. Тот факт, что Double наследник Number не играет никакой роли. ОТВЕТ: class A, method m : 1

Перечесляемые типы (enum)

Пример:
enum CoffeSize
{Big, Huge, Small};   -регистр не имеет значения в названиях. ; - если в внутри класа(опционально).

CoffeSize cs =  CoffeSize,Huge

enum CoffeeSize {
       BIG(8), HUGE(10), OVERWHELMING(16);
       CoffeeSize(int ounces) { // constructor
          this.ounces = ounces;
          }
       private int ounces; // an instance variable
       public int getOunces() {
       return ounces;
       }
}
class Coffee {
        CoffeeSize size; // each instance of Coffee has an enum
    public static void main(String[] args) {
    Coffee drink1 = new Coffee();
    drink1.size = CoffeeSize.BIG;
    Coffee drink2 = new Coffee();
    drink2.size = CoffeeSize.OVERWHELMING;
     System.out.println(drink1.size.getOunces()); // prints 8
    for(CoffeeSize cs: CoffeeSize.values())
    System.out.println(cs + " " + cs.getOunces());
 }
}
Which produces:
8
BIG 8
HUGE 10
OVERWHELMING 16

Интерфейс

Интерфейс  - (100% абстрактный) контракт, который говорит, что класс может делать, но не говорит как.
  1. все методы авт. - public abstact;
  2. методы не могут быть static, final, native, strictfp;
  3. все поля  - public static final;
  4. может extend другой интрефейс и только.


Модификаторы

Модификаторы доступа

  1. default (package-private) - доступ имеют классы только с одного и того же пакета.
  2. public - доступ имеют все классы, только нужно делать import, если с другого пакета.
  3. protected - как default доступ + доступ имеют классы наследники даже с других пакетов. Наследники (за границами пакета) имеют доступ только через наследование (inheritance), но никак не через ссылку на обьект.
  4. private - доступ имеет только клас владелец.
Клас может быть только public или default (кроме вложенных).

Другие модификаторы

  1. final(метод, клас, переменная) - класс не может иметь подклассов, не может быть extend. Единственный модификатор, который может применяться для локальных переменных. Если попытаться изменить переменную или переназначить или расширить клас, то будет Compilation error. Если это поле то оно должно быть присвоено значению, иначе Compilation error.
  2. abstract (метод, клас) - клас не может иметь экземпляр, может иметь абсрактные методы. (если пометить класс или метод abstract и final одновременно - будет Compilation error)
  3. strictfp(метод, клас) - все рассчеты в классе проводятся по станадарту IEEE 754 (плавающая точка).
  4. synchronized (метод) - доступ к методу может иметь только один thread одновременно.
  5. native - сообщает, что метод реализован на нейтив языку С, в конце метода ставится ";", как в абстрактом методе.
  6. transient(переменная) - переменная не будет сереализироваться.
  7. volatile(переменная) - используется для синхронизации.
  8. static(переманная класса только!!!, блок, вложенный клас, метод) - инициализируется до создания экзепляров обьектов. Нестатические элементы не могут использоваться в статических методах. 
final и abstract  не используются вместе.

Общие понятия

  1. Названия переменных(класов, интрефейсов) не могут начинаться с спецсимволов и цифр, кроме "$" "_".
  2. В одном файле может быть только 1 класс с идентификаторм public и много непубличных.
  3. Имя файла java-файла должно совпадать с названием public класса.
  4. Var-args: переменная переменной длины =) Синтаксис:void doStaff(int ... x). Метод ожидает на вход 0 или больше переменных. void doStaff(int ... x, int y) - illegal.
  5. Cohesion - созданный клас для определенно сфокусированной задачи.
  6. Coupling - связаность классов, стараться избегать.
Приоритет побитовых операций: 
! & ^ | && ||
&& || - ленивые операции, работают только с boolean.

Деление:
0/0 - java.lang.ArithmeticException
0/0.0 - NaN
0.0/0 - Nan
1/0.0 - Infinity
0.0/0.0 - NaN

Побитовый сдивг влево и вправо.
3>>4 тоже самое, что 3/ 2 в степени 4
3<<5 тоже самое, что 3 * 2 в степени 5
>>> - беззнаковый сдвиг
Перед выполнением любых арифметических операций значения типа byteshortchar автоматически преобразовываются к типу int. Поэтому результат умножения также будет иметь тип int, а значит во время компиляции будет обнаружена ошибка несоответствия типов – переменной byte k нельзя присвоить значение типа int.