betacode

Сравнение и Сортировка в Java

  1. Примитивные и ссылочные типы в Java.
  2. Как примитивный вид хранит в памяти
  3. Как ссылочный вид хранит в памяти
  4. Сравнения в Java
  5. Сравнение примитивных видов
  6. Сравнение ссылочных видов 
  7. Пример распорядка массива String
  8. Объекты, которые могут сравниваться друг с другом (Comparable)
  9. Упорядочить список (List)
  10. Упорядочить использование компаратора (Comparator)

1. Примитивные и ссылочные типы в Java.

Для начала, нам нужно уметь различать примитивный вид Primitive type) и ссылочный вид (reference type) в java.
В Java имеется 8 видов примитива.
  • Примитивный вид (Primitive type)
Type
Bit/Bytes
Range
boolean
1 bit
True or False
char
16 bit/ 2 bytes
0 to 65535
byte
8 bit/ 1 byte
-128 to 127
short
16 bit/ 2 bytes
-32768 to 32767
int
32 bits/ 4 bytes
-2147483648 to 2147483647
long
64 bits/ 8 bytes
-9,223,372,036,854,775,808 to -9,223,372,036,854,775,808
(-2^63 to -2^63)
float
32 bits/ 4 bytes
-3.4028235 x 10^38 to 3.4028235 x 10^38
double
64 bits/ 8 bytes
-1.7976931348623157 x 10^308 to 1.7976931348623157 x 10^308
Все другие виды расширены из Object, они являются ссылочными видами.

2. Как примитивный вид хранит в памяти

Для начала, вам нужно понять, что Java не гарантирует, что каждая переменная будет соответствовать позиции в памяти, например Java будет оптимизировать методом 'i' который будет сохранен в register, или даже может нигде не будет сохранен, если компилятор видит, что вы никогда не пользуетесь его значением, или он может отследить через код и использовать соответствующие значения напрямую.
Посмотрите код:
// Создать переменную 'a', и прикрепить значение 100.
int a = 100;

// Прикрепить новое значение 'a'
a = 200;

// Создать переменную 'b', прикрепить  b = a.
int b = a;
Тогда Java выполняет следующие действия:
  • TODO

3. Как ссылочный вид хранит в памяти

Когда вы видите оператор new (Например new Object()), Java создает новый объект в памяти. Вы объявляете переменную и инициализируете его значение через оператор new, напрмимер Object a = new Object(); Java создает новый объект в памяти, и ссылку 'a' указывающую на место памяти только что созданного объекта.

Когда вы объявляете переменную b Object b = a; никакой объект не создается в паияти, Java создает только ссылку 'b', указывающую на то же место куда указывает 'a'.
// Объявить и инициализировать объект.
Object a =  new Object();

// Прикрепить новое значение объекту 'a'.
a = new String("Text");

// Объявить объект 'b', и прикрепить к нему 'a'.
Object b =  a;
  • TODO

4. Сравнения в Java

В Java есть 2 вида сравнения:
  • Использование оператора ==
  • Использование метода (method) equals(..)
Оператор == используется для сравнения примитивных и ссылочных видов.
Оператор equals(..) это метод, использующийся только для ссылочных видов.

5. Сравнение примитивных видов

С примитивным видом у нас есть только единственный способ сравнения используя оператор ==, примитивные виды сравниваются друг с другом через их значения.
// Создать переменную 'a', прикрепить ей значение 200.
// Регион памяти (1) создан и содержит значение 200.
int a = 200;

// Создать переменную 'b', прикрепить ей значение 200.
// Регион памяти (2) создан и содержит значение  200.
int b = 200;

// Несмотря на то, что 'a' и 'b' указывают на 2 разных региона памяти.
// Сравнение a == b вернет результат true.
// Из-за примитивного сравнения друг с другом на основании значения.
boolean c = (a == b);

6. Сравнение ссылочных видов 

Использовать оператор == для сравнения видов ссылок
Когда вы сравниваете 2 объекта ссылки по оператору ==, значит сравнение позиций куда указывают 2 объекта ссылки. На самом деле это проверка, указывают ли эти 2 ссылки на один объект в памяти или нет.
Смотрите пример:
ReferenceEeDemo.java
package org.o7planning.tutorial.comparation;

public class ReferenceEeDemo {

	public static void main(String[] args) {

		// Примечание: С String 2 инициализация объекта ниже не одинаковая:
		String str1 = "String 1";
		String str2 = new String("String 1");

		// Оператор 'new' создает регион памяти (1)
		// содержащий String "This is text"
		// И 's1' это ссылка указывающая на регион (1).
		String s1 = new String("This is text");

		// Оператор 'new' создает регион памяти (2)
		// содержащий String "This is text"
		// И 's2' это ссылка указывающая на (2)
		String s2 = new String("This is text");

		// Использовать оператор == проверка 's1' и 's2'.
		// Дает результат false.
		// Это точно отличается с вашими мыслями.
		// Причиной является вид ссылки
		// оператор == сравнивает местонахождение в памяти, на который они указывают.
		boolean e1 = (s1 == s2); // false

		System.out.println("s1 == s2 ? " + e1);

		// Нет никакого оператора 'new'.
		// Java создает ссылку с названием 'obj'
		// И указывает на регион памяти, куда указывает 's1'.
		Object obj = s1;

		// 2 ссылки 'obj' и 's1' указывают на 1 регион памяти.
		// Возвращенным результатом является true.
		boolean e2 = (obj == s1); // true

		System.out.println("obj == s1 ? " + e2);
	}
	
}
Результат запуска программы:
s1 == s2 ? false
obj == s1 ? true
Использовать equals(..) для сравнения видов ссылок
StringComparationDemo.java
package org.o7planning.tutorial.comparation;

public class StringComparationDemo {

	public static void main(String[] args) {

		String s1 = new String("This is text");

		String s2 = new String("This is text");

		// Сравнить s1 и s2 через метод equals(..)
		boolean e1 = s1.equals(s2);

		// Возвратит результат true
		System.out.println("first comparation: s1 equals s2 ? " + e1);

		s2 = new String("New s2 text");

		boolean e2 = s1.equals(s2);

		// Возвратит результат false
		System.out.println("second comparation: s1 equals s2 ? " + e2);
	}

}
Результаты запуска программы:
first comparation: s1 equals s2 ? true
second comparation: s1 equals s2 ? false
Переопределить метод equals(Object)
Метод equals(Object) это метод имеющийся в class Object, каждый подкласс наследует этот метод. В некоторых случая вы можете переопределить этот метод в подклассах.
NumberOfMedals.java
package org.o7planning.tutorial.comparation.equals;

// Количество медалей
public class NumberOfMedals {

	// Количество золотых медалей
	private int goldCount;

	// Количество серебряных медалей.
	private int silverCount;

	// Количество бронзовых медалей
	private int bronzeCount;

	public NumberOfMedals(int goldCount, int silverCount, int bronzeCount) {
		this.goldCount = goldCount;
		this.silverCount = silverCount;
		this.bronzeCount = bronzeCount;
	}

	public int getGoldCount() {
		return goldCount;
	}

	public int getSilverCount() {
		return silverCount;
	}

	public int getBronzeCount() {
		return bronzeCount;
	}

	// Переопределить метод equals(Object) класса Object.
	@Override
	public boolean equals(Object other) {
		// Если other = null, то возвращает false.
		if (other == null) {
			return false;
		}
		// Если 'other' не является видом NumberOfMedals
		// то возвращает false.
		if (!(other instanceof NumberOfMedals)) {
			return false;
		}

		NumberOfMedals otherNoM = (NumberOfMedals) other;

		if (this.goldCount == otherNoM.goldCount && this.silverCount == otherNoM.silverCount
				&& this.bronzeCount == otherNoM.bronzeCount) {
			return true;
		}
		return false;
	}

}
NumberOfMedalsComparationDemo.java
package org.o7planning.tutorial.comparation.equals;

public class NumberOfMedalsComparationDemo {

	public static void main(String[] args) {

		// Достжения американской команды.
		NumberOfMedals american = new NumberOfMedals(40, 15, 15);

		// Достжения японской команды.
		NumberOfMedals japan = new NumberOfMedals(10, 5, 20);

		// Достжения корейской команды
		NumberOfMedals korea = new NumberOfMedals(10, 5, 20);

		System.out.println("Medals of American equals Japan ? " + american.equals(japan));

		System.out.println("Medals of Korea equals Japan ? " + korea.equals(japan));
	}

}
Результаты запуска примера:
Medals of American equals Japan ? false
Medals of Korea equals Japan ? true

7. Пример распорядка массива String

String это класс, объекты которого могут сравниваться друг с другом по правилам букв. Следующий пример иллюстрирует как рассположить массив String используя утилитарные методы имеющиеся в Java.
StringArraySortingDemo.java
package org.o7planning.tutorial.sorting;

import java.util.Arrays;

public class StringArraySortingDemo {

	public static void main(String[] args) {
		String[] fruits = new String[] { "Pineapple", "Apple", "Orange", "Banana" };

		// Использовать статический метод класса Arrays чтобы распределить.
		// Arrays.sort(Object[])
		Arrays.sort(fruits);

		for (int i = 0; i < fruits.length; i++) {
			System.out.println("fruits " + i + " : " + fruits[i]);
		}
	}

}
Результаты запуска примера:
fruits 0 : Apple
fruits 1 : Banana
fruits 2 : Orange
fruits 3 : Pineapple

8. Объекты, которые могут сравниваться друг с другом (Comparable)

// Вы пишете класс, симулирующий актера (Actor).
// Вы хотите распределить порядок актеров по правилу:
// Сравнить сначала по фамилии (lastName), потом сравнить по имени (firstName).
public class Actor {

	// Имя
	private String firstName;
	// Фамилия
	private String lastName;

}
Actor.java
package org.o7planning.tutorial.sorting;

// Чтобы сравнить друг с другом, класс Actor должен выполнить интерфейс Comparable.
public class Actor implements Comparable<Actor> {

	private String firstName;
	private String lastName;

	public Actor(String firstName, String lastName) {
		this.firstName = firstName;
		this.lastName = lastName;
	}

	public String getFirstName() {
		return firstName;
	}

	public String getLastName() {
		return lastName;
	}

	// Сравнить с другим объектом Actor
	// По правилу сначала сравнить lastName,
	// потом сравнить firstName.
	@Override
	public int compareTo(Actor other) {

		// Сравнить 2 String.
		int value = this.lastName.compareTo(other.lastName);

		// Если lastName 2-х объектов не равны.
		if (value != 0) {
			return value;
		}
		// Если lastName 2-х объектов одинаковы.
		// То сравнить fistName.
		value = this.firstName.compareTo(other.firstName);
		return value;
	}

}
ActorSortingDemo.java
package org.o7planning.tutorial.sorting;

public class ActorSortingDemo {

	public static void main(String[] args) {

		Actor actor1 = new Actor("Mischa", "Barton");
		Actor actor2 = new Actor("Christian", "Bale");
		Actor actor3 = new Actor("Joan", "Collins");
		Actor actor4 = new Actor("Gemma", "Arterton");
		Actor actor5 = new Actor("Daniel", "Craig");

		Actor[] actors = new Actor[] { actor1, actor2, actor3, actor4, actor5 };

		// Использовать алгоритм, чтобы перераспределить массив выше. 
		// Распределить по возрастанию объекты Actor.
		for (int i = 0; i < actors.length; i++) {

			for (int j = i + 1; j < actors.length; j++) {
				// Если actors[j] < actors[i]
				// То поменять местами друг с другом.
				if (actors[j].compareTo(actors[i]) < 0) {
					// Использовать временную переменную.
					// ​​​​​​​
					Actor temp = actors[j];
					actors[j] = actors[i];
					actors[i] = temp;
				}
			}
		}
		// Распечать элементы массива.
		for (int i = 0; i < actors.length; i++) {
			System.out.println(actors[i].getFirstName() + "  " + actors[i].getLastName());
		}

	}

}
Результаты запуска примера:
Gemma  Arterton
Christian  Bale
Mischa  Barton
Joan  Collins
Daniel  Craig
Использовать Arrays.sort(Object[]) чтобы расставить пример выше:
ActorSortingDemo2.java
package org.o7planning.tutorial.sorting;

import java.util.Arrays;

public class ActorSortingDemo2 {

	public static void main(String[] args) {

		Actor actor1 = new Actor("Mischa", "Barton");
		Actor actor2 = new Actor("Christian", "Bale");
		Actor actor3 = new Actor("Joan", "Collins");
		Actor actor4 = new Actor("Gemma", "Arterton");
		Actor actor5 = new Actor("Daniel", "Craig");

		Actor[] actors = new Actor[] { actor1, actor2, actor3, actor4, actor5 };

		// Использовать Arrays.sort(Object[]), чтобы распределить.
		Arrays.sort(actors);

		// Распечать элементы массива.
		for (int i = 0; i < actors.length; i++) {
			System.out.println(actors[i].getFirstName() + "  " + actors[i].getLastName());
		}

	}
}

9. Упорядочить список (List)

Вы можете посмотреть так же статью Java Collection Framework по ссылке:
Пример:
ListSortingDemo.java
package org.o7planning.tutorial.sorting;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class ListSortingDemo {

	public static void main(String[] args) {

		Actor actor1 = new Actor("Mischa", "Barton");
		Actor actor2 = new Actor("Christian", "Bale");
		Actor actor3 = new Actor("Joan", "Collins");
		Actor actor4 = new Actor("Gemma", "Arterton");
		Actor actor5 = new Actor("Daniel", "Craig");

		// Список содержащий элементы, которые можно сравнить друг с другом.
		// (Comparable)
		List<Actor> actors = new ArrayList<Actor>();

		actors.add(actor1);
		actors.add(actor2);
		actors.add(actor3);
		actors.add(actor4);
		actors.add(actor5);

		// Использовать метод Collections.sort(List)
		// чтобы упорядочить список (List)
		Collections.sort(actors);

		for (Actor actor : actors) {
			System.out.println(actor.getFirstName() + "  " + actor.getLastName());
		}

	}

}

10. Упорядочить использование компаратора (Comparator)

В примерах выше, мы расставляли массив или список. Сами элементы имеют возможность сравниваться друг с другом (Из-за применения interface Comparable). Вопрос в том, что можно ли расставить объекты, с классами не применяющими interface Comparable.В данном случае вам нужно предоставить компаратор (Comparator). Это правила для расстановки объектов.
Person.java
package org.o7planning.tutorial.comparator;

public class Person {

  private int age;
  private String fullName;

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

  public int getAge() {
      return age;
  }

  public String getFullName() {
      return fullName;
  }
}
PersonComparator.java
package org.o7planning.tutorial.comparator;

import java.util.Comparator;

// Данный класс выполняет интерфейс Comparator<Person>.
// Это правило для сравнения объектов Person.
public class PersonComparator implements Comparator<Person> {

	// Переопределить (override) метод compare.
	// Дать ясные правила сравнения 2-х объектов Person.
	@Override
	public int compare(Person o1, Person o2) {
		// Два объекта null считаются равными.
		if (o1 == null && o2 == null) {
			return 0;
		}
		// Если o1 является null, считается что o2 больше
		if (o1 == null) {
			return -1;
		}
		// Если o2 является null, считается что o1 больше.
		if (o2 == null) {
			return 1;
		}
		// Правило:
		// Распределить по возрастанию возраста.
		int value = o1.getAge() - o2.getAge();
		if (value != 0) {
			return value;
		}
		// Если возраст равен, то сравнить fullName.
		// Сравнить по Alphabet (алфавиту).
		value = o1.getFullName().compareTo(o2.getFullName());
		return value;
	}

}
ComparatorSortingDemo.java
package org.o7planning.tutorial.comparator;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

public class ComparatorSortingDemo {

	public static void main(String[] args) {
		Person person1 = new Person("Marry", 20);
		Person person2 = new Person("Tom", 21);
		Person person3 = new Person("Daniel", 21);
		Person person4 = new Person("Mischa", 18);
		Person person5 = new Person("Christian", 20);

		// Массив еще не упорядочен.
		Person[] array = new Person[] { person1, person2, person3, person4, person5 };

		// Упорядочить массив, используя: <T> Arrays.sort(T[],Comparator<? supers T>).
		// И предоставить Comparator (Компаратор).
		Arrays.sort(array, new PersonComparator());

		for (Person person : array) {
			System.out.println("Person: " + person.getAge() + " / " + person.getFullName());
		}

		System.out.println("------------------------");

		// Для списка:
		List<Person> list = new ArrayList<Person>();
		list.add(person1);
		list.add(person2);
		list.add(person3);
		list.add(person4);
		list.add(person5);

		// Упорядочить список используя:
		// <T> Collections.sort(List<T>, Comparator<? supers T>).
		// И предоставить Comparator (Компаратор).
		Collections.sort(list, new PersonComparator());

		for (Person person : list) {
			System.out.println("Person: " + person.getAge() + " / " + person.getFullName());
		}
	}

}
Результаты запуска примера:
Person: 18 / Mischa
Person: 20 / Christian
Person: 20 / Marry
Person: 21 / Daniel
Person: 21 / Tom
------------------------
Person: 18 / Mischa
Person: 20 / Christian
Person: 20 / Marry
Person: 21 / Daniel
Person: 21 / Tom

Java Basic

Show More