#string compareto
Explore tagged Tumblr posts
tpointtech · 2 months ago
Text
"Mastering string compareTo: How Strings Really Stack Up in Java"
Comparing two strings might sound like a basic task, but when it comes to programming—especially in Java—there’s more happening under the hood. Whether you’re sorting a list of names, validating user input, or organizing data alphabetically, the method string compareTo is your trusty sidekick.
In this blog, we’ll unpack how the compareTo method works, what it really compares, and when to use it in real-world scenarios. No code required—just a clear and practical understanding of one of Java’s most essential string tools.
Tumblr media
What Is string compareTo All About?
At its core, string compareTo is a method used to compare two strings lexicographically—that means it checks how they stack up in dictionary order. This method belongs to the String class in Java and returns an integer that tells you the result of the comparison.
But here’s where it gets interesting: it doesn’t just say "equal" or "not equal." Instead, it tells you how two strings differ in order, giving you valuable information you can use in sorting, decision-making, and data processing.
Breaking Down the CompareTo Results
When you compare two strings using string compareTo, Java returns one of three possible outcomes:
Zero (0): The strings are exactly the same.
A positive number: The first string is lexicographically greater than the second.
A negative number: The first string is lexicographically less than the second.
So when you see a result like -3 or 4, it’s not about the actual number—it’s about the sign (negative, zero, or positive) that matters most.
Lexicographical Comparison: What Does That Really Mean?
"Lexicographical" might sound fancy, but it’s basically how words are ordered in the dictionary. Java compares strings character by character, based on their Unicode values.
Let’s imagine comparing “Apple” to “Banana”:
“A” comes before “B” in the alphabet.
Therefore, "Apple".compareTo("Banana") will return a negative number.
This rule applies even if the strings are almost identical. For example:
"Code" vs "Coder" → The shorter one comes first if all earlier characters match.
It’s like comparing two paths in a forest: you walk together until one path splits off—whichever turns first determines which one is “greater” or “less.”
When and Why You’d Use string compareTo
You might be wondering: where does this comparison method actually come in handy? Here are a few common use cases:
1. Sorting Strings
Whether you’re building a contact list or sorting categories alphabetically, string compareTo helps establish the order. Most sorting algorithms under the hood rely on such comparisons to figure out which string should come first.
2. Validating Input
Need to check if a user typed the exact phrase you're expecting? Using string compareTo is one way to verify input matches your criteria without relying on basic equality checks alone.
3. Creating Custom Sorting Logic
In more advanced scenarios, you might sort strings based on specific business rules. For example, ignoring case or placing certain words before others. While compareTo gives you a default behavior, it can be extended with custom logic when needed.
Things to Keep in Mind
As helpful as string compareTo is, here are a few nuances to remember:
Case Sensitivity Matters: "apple" and "Apple" will not be considered equal. The method is case-sensitive by default.
Null Safety: Avoid comparing strings that might be null, as calling compareTo on a null reference will throw an exception.
Consistency Counts: Always use a consistent comparison strategy, especially when dealing with sorted data structures or search functions.
If you need to compare strings without case sensitivity, many developers opt to convert both strings to lowercase or uppercase before comparing them.
Alternatives and Enhancements
Sometimes, the basic string compareTo isn’t quite enough. For example, if you want to:
Ignore case: Use a method designed for case-insensitive comparison.
Handle locales and special characters: Use a more advanced comparison mechanism like Collator for culturally aware sorting.
But in most situations, string compareTo provides exactly what you need in a lightweight and reliable way.
Final Thoughts: Comparing the Right Way
String comparison may seem simple on the surface, but understanding how methods like string compareTo work gives you greater control over how your application behaves. It's one of those hidden gems in programming—subtle, powerful, and essential in the right hands.
Next time you find yourself sorting, filtering, or validating text in your Java programs, remember this: knowing how strings stack up can make all the difference.
With a solid grasp of string compareTo, you’re well on your way to writing cleaner, smarter, and more predictable code.
0 notes
tpointtechblogs · 2 months ago
Text
5 Reasons to Use an HTML Compiler for Your Project
Discover how an HTML compiler can streamline your web development process. From improving code organization to enhancing performance, an HTML compiler offers powerful benefits for both beginners and professionals. This guide explores five compelling reasons why integrating an HTML compiler into your workflow can save time, reduce errors, and boost overall project efficiency.
Visit the blog: https://tucsonnewsplus.com/5-reasons-to-use-an-html-compiler-for-your-projects
follow for more blogs:
https://postr.blog/tied-or-not-let-compareto-decidehttps://australianewsnetwork.com/split-it-like-its-hot-c-string-breakdown/https://www.franceclassifieds.com/ctrlaltcrack-it-fun-with-c-interview-questionshttps://guest-post.org/not-so-standard-playing-with-deviation-in-numpy/https://dev.to/tpointech/linux-magic-rename-folders-with-command-line-sorcery-5go2
0 notes
vatt-world · 8 months ago
Text
hi--
public class EmployeeStore { public static void main(String[] args) { // TreeMap with salary as the key and Employee as the value TreeMap employeeMap = new TreeMap<>(); // Adding employees to the TreeMap employeeMap.put(50000, new Employee("Alice", 50000)); employeeMap.put(70000, new Employee("Bob", 70000)); employeeMap.put(60000, new Employee("Charlie", 60000)); employeeMap.put(80000, new Employee("David", 80000)); // Displaying employees sorted by salary for (Map.Entry<Integer, Employee> entry : employeeMap.entrySet()) { System.out.println(entry.getValue()); } }
/// public class EmployeeStore { public static void main(String[] args) { // TreeMap with custom comparator to sort by salary, then by id TreeMap employeeMap = new TreeMap<>(); // Adding employees to the TreeMap employeeMap.put(new EmployeeKey(50000, 1), new Employee(1, "Alice", 50000)); employeeMap.put(new EmployeeKey(70000, 2), new Employee(2, "Bob", 70000)); employeeMap.put(new EmployeeKey(60000, 3), new Employee(3, "Charlie", 60000)); employeeMap.put(new EmployeeKey(50000, 4), new Employee(4, "David", 50000)); // Displaying employees sorted by salary, then by id for (Map.Entry<EmployeeKey, Employee> entry : employeeMap.entrySet()) { System.out.println(entry.getValue()); } }
}
// Helper class to represent a composite key of salary and id class EmployeeKey implements Comparable { private int salary; private int id;public EmployeeKey(int salary, int id) { this.salary = salary; this.id = id; } @Override public int compareTo(EmployeeKey other) { if (this.salary != other.salary) { return Integer.compare(this.salary, other.salary); } else { return Integer.compare(this.id, other.id); } }
}
///
public class EmployeeStreamExample { public static void main(String[] args) { // Creating a list of employees List employees = new ArrayList<>(); employees.add(new Employee(1, "Alice", 50000)); employees.add(new Employee(2, "Bob", 70000)); employees.add(new Employee(3, "Charlie", 60000)); employees.add(new Employee(4, "David", 50000)); // Using Stream API to sort by salary, then by id if salaries are equal List<Employee> sortedEmployees = employees.stream() .sorted(Comparator.comparingInt(Employee::getSalary) .thenComparingInt(Employee::getId)) .collect(Collectors.toList()); // Displaying the sorted employees sortedEmployees.forEach(System.out::println); }
}
/// public class EmployeeStreamExample { public static void main(String[] args) { // Creating a list of employees List employees = new ArrayList<>(); employees.add(new Employee(1, "Alice", 50000)); employees.add(new Employee(2, "Bob", 70000)); employees.add(new Employee(3, "Charlie", 60000)); employees.add(new Employee(4, "David", 50000)); // Getting an employee by id int searchId = 3; Optional<Employee> employee = employees.stream() .filter(e -> e.getId() == searchId) .findFirst(); // Checking if an employee was found and displaying the result if (employee.isPresent()) { System.out.println("Employee found: " + employee.get()); } else { System.out.println("Employee with id " + searchId + " not found."); } }
}
///
public class EmployeeStreamExample { public static void main(String[] args) { // Creating a list of employees List employees = new ArrayList<>(); employees.add(new Employee(1, "Alice", 50000.0)); employees.add(new Employee(2, "Bob", 70000.0)); employees.add(new Employee(3, "Charlie", 60000.0)); employees.add(new Employee(4, "David", 50000.0)); // Converting to a Map with name as the key and salary as the value Map<String, Double> employeeSalaryMap = employees.stream() .collect(Collectors.toMap(Employee::getName, Employee::getSalary)); // Displaying the map employeeSalaryMap.forEach((name, salary) -> System.out.println("Name: " + name + ", Salary: " + salary)); }
}
/ Creating a list of employees List employees = new ArrayList<>(); employees.add(new Employee(1, "Alice", 50000)); employees.add(new Employee(2, "Bob", 70000)); employees.add(new Employee(3, "Charlie", 60000)); employees.add(new Employee(4, "David", 50000)); // Using Stream API to sort by salary, then by id if salaries are equal List<Employee> sortedEmployees = employees.stream() .sorted(Comparator.comparingInt(Employee::getSalary) .thenComparingInt(Employee::getId)) .collect(Collectors.toList()); // Displaying the sorted employees sortedEmployees.forEach(System.out::println); }
//////
public static void main(String[] args) { // Creating a list of employees List employees = new ArrayList<>(); employees.add(new Employee(1, "Alice", 50000)); employees.add(new Employee(2, "Bob", 70000)); employees.add(new Employee(3, "Charlie", 60000)); employees.add(new Employee(4, "David", 50000)); // Getting an employee by id int searchId = 3; Optional<Employee> employee = employees.stream() .filter(e -> e.getId() == searchId) .findFirst(); // Checking if an employee was found and displaying the result if (employee.isPresent()) { System.out.println("Employee found: " + employee.get()); } else { System.out.println("Employee with id " + searchId + " not found."); }
filter(e -> e.getId() == searchId) filters the stream to find employees with an id matching searchId. findFirst() returns an Optional, containing the first employee that matches the criteria, if any. ////////////////
List employees = new ArrayList<>(); employees.add(new Employee(1, "Alice", 50000.0)); employees.add(new Employee(2, "Bob", 70000.0)); employees.add(new Employee(3, "Charlie", 60000.0)); employees.add(new Employee(4, "David", 50000.0)); // Converting to a Map with name as the key and salary as the value Map<String, Double> employeeSalaryMap = employees.stream() .collect(Collectors.toMap(Employee::getName, Employee::getSalary)); // Displaying the map employeeSalaryMap.forEach((name, salary) -> System.out.println("Name: " + name + ", Salary: " + salary)); }
employees.stream() creates a stream from the list of employees. collect(Collectors.toMap(Employee::getName, Employee::getSalary)) collects the stream into a Map where: Employee::getName is used as the key (employee’s name). Employee::getSalary is used as the value (employee’s salary). ////////////// If employee names are not unique, you can handle duplicates by specifying a merge function when using Collectors.toMap
List employees = new ArrayList<>(); employees.add(new Employee(1, "Alice", 50000.0)); employees.add(new Employee(2, "Bob", 70000.0)); employees.add(new Employee(3, "Charlie", 60000.0)); employees.add(new Employee(4, "Alice", 55000.0)); // Duplicate name "Alice" with different salary // Converting to a Map with name as the key and salary as the value, keeping the higher salary for duplicates Map<String, Double> employeeSalaryMap = employees.stream() .collect(Collectors.toMap( Employee::getName, Employee::getSalary, Double::max // Merge function to keep the higher salary for duplicate names )); // Displaying the map employeeSalaryMap.forEach((name, salary) -> System.out.println("Name: " + name + ", Salary: " + salary)); }
Merge Function: In Collectors.toMap, the third argument is a merge function (Double::max), which is used to resolve duplicate keys (in this case, duplicate employee names). Double::max ensures that if two employees have the same name, the one with the higher salary is kept. Alternatively, you could use Double::min to keep the lower salary or (s1, s2) -> s1 + s2 to sum the salaries. //////////////
Spring Boot 3 Java 17 as the Minimum Requirement:
Spring Boot 3 requires Java 17 or later, taking advantage of new language features and performance improvements available in recent Java versions. Native Image Support with GraalVM: //////////////
Spring Data JPA is a part of the Spring Data framework that simplifies the implementation of JPA (Java Persistence API) repositories. It provides abstractions over JPA and simplifies the database access layer, making it easier to perform CRUD operations, pagination, sorting, and more without writing boilerplate code.
//////////////
public interface EmployeeRepository extends JpaRepository { List findByName(String name); // Derived query@Query("SELECT e FROM Employee e WHERE e.salary > :salary") List<Employee> findEmployeesWithSalaryGreaterThan(@Param("salary") double salary);
}
findByName(String name): Spring Data JPA automatically interprets this method name and generates the query to find employees by name. findEmployeesWithSalaryGreaterThan(double salary): This custom query uses the @Query annotation with JPQL (Java Persistence Query Language) to find employees with a salary greater than a specified amount.
……..
It defines annotations (like @Entity, @Table, @Id, etc.) and APIs (like EntityManager) for managing the lifecycle of entities and querying the database. ////
o find the employee with the maximum salary in a Spring Data JPA repository, you have several options. Here’s how to do it using different approaches.
@Query("SELECT e FROM Employee e WHERE e.salary = (SELECT MAX(e2.salary) FROM Employee e2)") Optional findEmployeeWithMaxSalary();
//////
public interface EmployeeRepository extends JpaRepository { Optional findTopByOrderBySalaryDesc(); } …………
public Optional getEmployeeWithMaxSalary() { return employeeRepository.findAll() .stream() .max(Comparator.comparingDouble(Employee::getSalary)); } ………………
public interface EmployeeRepository extends JpaRepository {@Query("SELECT e FROM Employee e WHERE e.salary > :salary") List<Employee> findEmployeesWithSalaryGreaterThan(@Param("salary") double salary);
} …………………. ublic interface EmployeeRepository extends JpaRepository {@Query("SELECT e.id FROM Employee e WHERE e.salary > :salary") List<Long> findEmployeeIdsWithSalaryGreaterThan(@Param("salary") double salary);
}
/////////////////
public interface EmployeeRepository extends JpaRepository {@Query("SELECT e.id AS id, e.name AS name FROM Employee e WHERE e.salary > :salary") List<EmployeeIdNameProjection> findEmployeeIdAndNameWithSalaryGreaterThan(@Param("salary") double salary);
}
///////////////// Ensure @SpringBootApplication is on the Main Class The @SpringBootApplication annotation is crucial, as it enables component scanning, autoconfiguration, and configuration properties. Make sure it’s present on your main class:
@Query("SELECT new com.example.demo.EmployeeIdName(e.id, e.name) FROM Employee e WHERE e.salary > :salary") List findEmployeeIdAndNameWith
//………….
Annotate Classes with @Component, @Service, @Repository, etc. Spring Boot requires beans to be annotated with @Component or a stereotype annotation like @Service, @Repository, or @Controller so that they’re detected by component scanning. Ensure your classes are annotated properly:
//………….
In Maven, a BOM (Bill of Materials) is a special type of dependency that manages dependency versions across multiple modules or dependencies. It’s commonly used to ensure consistent versions of libraries, especially in Spring Boot projects. The BOM prevents version conflicts by specifying a set of compatible dependencies.
//…………. How Works Centralized Version Control: You declare versions of dependencies in the parent POM without specifying them in the child POMs. Inheritance: Child POMs inherit these dependencies and can add them without specifying the version, as the version is inherited from in the parent POM. Scope Control: You can set the scope for dependencies centrally, and child modules will use these settings.
//…………. Singleton: Ensures a class has only one instance and provides a global point of access to it. Useful for resources like databases, configuration managers, and logging.
Factory Method: Provides an interface for creating objects but allows subclasses to alter the type of objects created. Useful when the exact type of object isn’t known until runtime.
Facade: Provides a simplified interface to a complex subsystem, making it easier to use.
Flyweight: Shares objects to support large numbers of fine-grained objects efficiently. Useful for objects that are costly to create.
Proxy: Provides a surrogate or placeholder to control access to another object, useful for lazy initialization, access control, logging, etc.
State: Allows an object to alter its behavior when its internal state changes, appearing to change its class.
Strategy: Defines a family of algorithms and makes them interchangeable, allowing the algorithm to vary independently from the clients.''
////////////
Singleton Pattern Usage in Spring: By default, Spring beans are singletons. This means a single instance of each bean is created and shared across the application context.
Purpose: Ensures that only one instance of a bean is created per Spring container, promoting memory efficiency and shared resource usage. ……………
Factory Method Pattern Usage in Spring: Spring uses the Factory Method pattern to create bean instances. The BeanFactory and ApplicationContext containers in Spring serve as factories for creating and managing beans.
Example: The FactoryBean interface allows you to define a factory for creating specific bean instances. ……………….. Dependency Injection (DI) / Inversion of Control (IoC) Usage in Spring: Dependency Injection is a fundamental pattern in Spring, where the framework manages the dependencies of objects rather than the objects creating their own dependencies.
Example: Using @Autowired or constructor injection to inject dependencies …………………….
Spring provides several other scopes for beans:
Prototype: A new instance is created every time the bean is requested.
java Copy code @Scope("prototype") @Component public class MyPrototypeService { } Request (Web Application): A new bean instance is created for each HTTP request.
java Copy code @Scope("request") @Component public class MyRequestScopedService { } Session (Web Application): A new bean instance is created for each HTTP session.
java Copy code @Scope("session") @Component public class MySessionScopedService { } Application (Web Application): A single instance is created for the lifecycle of the ServletContext.
////////////////////////////
How to Specify Bean Scope To specify a different scope for a bean, use the @Scope annotation along with @Component, @Service, @Repository, or @Controller:
java Copy code import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Service;
@Service @Scope("prototype") // Change scope to prototype public class MyService {
///////////
microservices architecture, managing session scope across distributed services requires a different approach from traditional monolithic applications. Since each microservice is independently deployed and has its own memory space, session data cannot be stored in the memory of a single service instance. Here are some best practices and solutions for managing session scope in a microservices environment:
Stateless Microservices with Token-Based Authentication The recommended approach in a microservices architecture is to make services stateless, meaning each request should contain all the information required to process it, and no session data should be stored on the server.
JWT (JSON Web Tokens): Instead of storing session data on the server, you can use JWTs to encode user information. The token is then passed along with each request, allowing the microservices to authenticate and authorize the user without storing session data. OAuth2/OpenID Connect: Use OAuth2 or OpenID Connect with a central identity provider (such as Keycloak, Okta, or Auth0) for managing authentication and authorization. These protocols often use access tokens or ID tokens that services can verify without storing session data.
/////////////////
Spring Session for Distributed Session Management Spring Session is a project that provides support for managing session data in a distributed environment, such as Redis, JDBC, or Hazelcast. It decouples session management from the container (e.g., Tomcat) and centralizes it in a shared data store.
Example of Spring Session with Redis:
Add Dependencies: Add the Spring Session and Redis dependencies in your pom.xml.
////////////
Open/Closed Principle (OCP) Definition: Software entities (classes, modules, functions) should be open for extension but closed for modification.
Explanation: You should be able to add new functionality to a class without modifying its existing code. This is typically achieved using inheritance, interfaces, or polymorphism.
Single Responsibility Principle: Each class should have one responsibility. Open/Closed Principle: Classes should be open to extension but closed to modification. Liskov Substitution Principle: Subclasses should be replaceable for their base classes. Interface Segregation Principle: Avoid forcing clients to implement interfaces they don’t use. Dependency Inversion Principle: Depend on abstractions, not on conc
In a microservices architecture, managing session scope across distributed services requires a different approach from traditional monolithic applications. Since each microservice is independently deployed and has its own memory space, session data cannot be stored in the memory of a single service instance. Here are some best practices and solutions for managing session scope in a microservices environment:
Stateless Microservices with Token-Based Authentication The recommended approach in a microservices architecture is to make services stateless, meaning each request should contain all the information required to process it, and no session data should be stored on the server.
JWT (JSON Web Tokens): Instead of storing session data on the server, you can use JWTs to encode user information. The token is then passed along with each request, allowing the microservices to authenticate and authorize the user without storing session data.
OAuth2/OpenID Connect: Use OAuth2 or OpenID Connect with a central identity provider (such as Keycloak, Okta, or Auth0) for managing authentication and authorization. These protocols often use access tokens or ID tokens that services can verify without storing session data.
0 notes
phamvana · 1 year ago
Text
Tập 5| Lập trình hướng đối tượng JAVA | String
Trong java, string(chuỗi) là một đối tượng biểu diễn một chuỗi các giá trị char. Lớp String trong java cung c��p rất nhiều các phương thức để thực hiện các thao tác với chuỗi như: compare(), concat(), equals(), split(), length(), replace(), compareTo(), intern(), substring(), … Lớp java.lang.String được implements từ các interface Serializable, Comparable and CharSequence. Các phương thức của…
Tumblr media
View On WordPress
0 notes
rohit-69 · 1 year ago
Text
Java String Operations: Unraveling the Magic
An IntroductionStrings are the fundamental building blocks of all computer languages. They save text, characters, and even our personal sentiments for the digital universe. Strings in Java are more than simply a collection of letters; they are flexible objects with special abilities. Buckle up as we journey through the wonderful world of string operations!
Creating Strings Before we go into the details, let's look at how strings are created. There are two methods for creating a string object:
1.String Literal: Imagine string literals as miniature magic spells. When you declare a string with double quotes, Java examines its mysterious "string constant pool." If the identical spell (string) already exists there, it will provide you a reference to it. Otherwise, a new magical instance is summoned. For example: '''java String s1 = "hello"; // Makes a reference to the existing "hello" spell. String s2 = "hello"; // Reuse the same spell (no new instance) '''
2. Using the 'new' keyword: Sometimes we need new spells. When you use 'new' to generate a string, Java creates a new instance in ordinary heap memory. The literal is still present in the continuous pool. For example: '''java String s3 = new String("world"); // Creates a new instance on the heap '''
Common String Operation
Now that we have summoned So, let's use our wands (or keyboards) to perform some magic:
1. Concatenation: Joining strings is similar to mixing potions. Use the '+' operator to merge them. '''java string fullName = firstName + " " + lastName; // "Harry Potter" '''
2. Length: Interested in the length of your incantation? The 'length()' technique reveals the following: '''java int spellLength = fullName.length(); // 12 '''
3. Comparison: To determine whether two spells are equal, use 'equals()' or 'compareTo()': '''java boolean sameSpell = s1.equals(s2); // True integer spellComparison = s1.compareTo(s2); '''
4. Substring: Extract a piece of the spellbook: '''java string potion = fullName.substring(6); // "Potter" '''
5. Replacing Ingredients: Replace ingredients with'replace()'. '''java: String newSpell = fullName.Replace "Harry" with "Hermione Potter".
6. Splitting Spells: Split a large spell into a series of smaller ones. '''java String[] words = fullName.split(" "); // ["Harry", "Potter"] '''
Why String Magic Matters
- Immutability: Strings, like ancient scrolls, do not alter once written. This immutability assures that your magical code remains stable. - String Pool: The constant pool conserves memory by reusing existing spells. Efficiency at its best! - StringBuilder and StringBuffer: These classes come in handy when mutable spells are required (for example, dynamic incantations).
Conclusion
Strings in Java are more than just words; they are the incantations that define our digital magic. Whether you're concatenating, comparing, or separating, keep in mind that each string tells a story made up of characters and bytes.
So go forth, young wizard, and use your strings wisely. May your code be bug-free and your magic enchanting! 🌟✨
if you want to know more about this topic or any other topic you can visit analyticsjobs.in or click here
0 notes
javatute673 · 2 years ago
Text
How does String compareTo() method work in Java
Tumblr media
0 notes
shajithwikiod · 3 years ago
Text
TreeSet and HashSet
A set is a collection of objects in which no object occurs more than once. Sets implement all the methods in the interface Collection, but do so in a way that ensures that no element occurs twice in the set. For example, if set is an object of type Set, then set.add(obj) will have no effect on the set if obj is already an element of the set. Java has two classes that implement the interface Set: java.util.TreeSet and java.util.HashSet.
In addition to being a Set, a TreeSet has the property that the elements of the set are arranged into ascending sorted order. An Iterator for a TreeSet will always visit the elements of the set in ascending order.
A TreeSet cannot hold arbitrary objects, since there must be a way to determine the sorted order of the objects it contains. Ordinarily, this means that the objects in a set of type TreeSet should implement the interface Comparable and that obj1.compareTo(obj2) should be defined in a reasonable way for any two objects obj1 and obj2 in the set. Alter-natively, an object of type Comparator can be provided as a parameter to the constructor when the TreeSet is created. In that case, the compareTo() method of the Comparator will be used to compare objects that are added to the set.
A TreeSet does not use the equals() method to test whether two objects are the same. Instead, it uses the compareTo() method. This can be a problem. Recall from Subsection 10.1.6 that compareTo() can consider two objects to be the same for the purpose of the comparison even though the objects are not equal. For a TreeSet, this means that only one of those objects can be in the set. For example, if the TreeSet contains mailing addresses and if the compareTo() method for addresses just compares their zip codes, then the set can contain only one address in each zip code. Clearly, this is not right! But that only means that you have to be aware of the semantics of TreeSets, and you need to make sure that compareTo() is defined in a reasonable way for objects that you put into a TreeSet. This will be true, by the way, for Strings, Integers, and many other built-in types, since the compareTo() method for these types considers two objects to be the same only if they are actually equal.
In the implementation of a TreeSet, the elements are stored in something similar to a binary sort tree. (See Subsection 9.4.2.) However, the data structure that is used is balanced in the sense that all the leaves of the tree are at about the same distance from the root of the tree. This ensures that all the basic operations—inserting, deleting, and searching—are efficient, with worst-case run time (-)(log(n)), where n is the number of items in the set.
Visit more Information: https://www.wikiod.com/w/Category:Java_Language
0 notes
pius2017 · 4 years ago
Text
What Collection Framework classes can and can't do. Which of the following things can be done by collection classes (List, Set, or Map)? If you can do it, outline how, mentioning relevant methods, else say that it is impossible and why
What Collection Framework classes can and can’t do. Which of the following things can be done by collection classes (List, Set, or Map)? If you can do it, outline how, mentioning relevant methods, else say that it is impossible and why
3.       What Collection Framework classes can and can’t do. Which of the following things can be done by collection classes (List, Set, or Map)? If you can do it, outline how, mentioning relevant methods, else say that it is impossible and why. A program is designed to have a TreeMap<Customer, String>, but Customer has no compareTo method. Is it possible to get the TreeMap to work without…
View On WordPress
0 notes
tpointtech · 3 months ago
Text
0 notes
arshikasingh · 10 months ago
Text
String Comparison in Java by using compareTo() Method
Let us see an example of string comparison in Java by using compareTo() Method:
Tumblr media
2 notes · View notes
tinchicus · 4 years ago
Text
Java / El metodo compareTo
Java / El metodo compareTo, hoy veremos un metodo que nos permite comparar dos cadenas para saber si son iguales o cual aparece primero en una busqueda, espero les sea util!
Bienvenidos sean a este post, hoy hablaremos sobre uno de los metodos para la clase String. Este metodo nos permite comparar entre una cadena y un objeto u otra cadena, su sintaxis es la siguiente: variable.compareTo(objeto); variable.compareTo(cadena); En todos los casos tomara la variable que pasemos y la compara con el objeto o la cadena informada, siempre nos devolvera un valor de tipo…
Tumblr media
View On WordPress
0 notes
inlarn · 4 years ago
Text
Write a java program to arrange strings in alphabetical order. Sorting names in alphabetical order with a Java program. Enter the array’s size, then all of the names in the array. We can now quickly arrange names in alphabetical order using the compareTo operator.The Java Program to Sort Names in Alphabetical Order source code is available here.
https://inlarn.com/write-a-java-program-to-arrange-strings-in-alphabetical-order/
0 notes
memleketyazilim · 4 years ago
Text
C# WFA String Metotlar Nasıl Kullanılır
C# WFA String Metotlar Nasıl Kullanılır
/* Sahip oldugunuz metinsel degerlerin ozelliklerini degistirmek icin kullanilan metotlardir. Ornegin, kelimeleri parcalamak, eklemek, harflerin yerlerini degistirmek, bosluk temizlemek vs... */ string gelen_deger; string kontrol_deger; #region Compare private void btnCompare_Click(object sender, EventArgs e) { //CompareTo => Metodu kullandiginiz string degerle metoda verdiginiz parametredeki…
Tumblr media
View On WordPress
0 notes
siva3155 · 6 years ago
Text
300+ TOP Dart Programming Interview Questions and Answers
Dart Programming Interview Questions for freshers experienced :-
1. What is Dart? Dart is an application programming language. It is used to build web, server and mobile applications. 2. Who is the developer of Dart? Google is the developer of Dart. 3. How to create a simple program? The following code for simple program: main() { print("Hello World!"); } 4. What are the ways to execute Dart Program? There are two ways to execute Dart program: Via the terminal. Via the WebStrom IDE. 5. Is Dirt is case sensitive programming language? Yes, Dirt is case sensitive programming language. 6. What are the data types in Dart language? There are following data types in Dart language. Numbers Strings Booleans Lists Maps 7. What is type-checking in Dart? In Dart, type-checking is used to check that a variable hold only specific to a data type. ----------------------------------------------------------------- String name = 'Smith'; int num = 10; ----------------------------------------------------------------- void main() { String name = 1; // variable Not Match } 8. What are various string functions in Dart? There are given various string functions: String Methods Description toLowerCase() It converts all string characters in to lower case. toUpperCase() It converts all string characters in this to upper case. trim() It returns the string without any whitespace. compareTo() It compares this object to another. 9. What are the types of list in Dirt? There are two types of list in Dirt that are given below: Fixed Length List : (length fixed) Growable List: (Length can change at runtime. 10. What is the syntax for declare the map using a Map Constructor? Map declaration syntax is: var identifier = new Map()
Tumblr media
Dart Programming Interview Questions 11. What is rune in Dart? In Dart, rune is an integer representing Unicode code point. 12. Does Dart has a syntax for declaring interfaces? No, Dart has not syntax for declaring interface. 13. What is Lambda Function? A Lambda function is a concise mechanism to represent functions. These functions are known as Arrow functions. Example: void main() { printMsg(); print(test()); } printMsg()=> print("hello"); int test()=>123; // returning function 14. What is the use of this keyword in Dart? In Dart, this keyword refers to the current instance of the class. void main() { Car c1 = new Car('E1001'); } class Car { String engine; Car(String engine) { this.engine = engine; print("The engine is : "); } } 15. What are Getters and Setters? Getters and Setters allow the program to initialize and retrieve the value of class fields. It is also known as accessors and mutators. 16. What are the differences between Dart and JavaScript? The differences between Dart and JavaScript are given below in table. Feature Dart JavaScript Type system Optional, dynamic Weak, dynamic Classes Yes, Single inheritances Prototypical Interfaces Yes, Multiple interfaces No Concurrency Yes, with isolates Yes, with HTML5 web workers. 17. Which command is used to compile Dart into JavaScript? The following command is used to compile Dart into JavaScript: dart2js - - out=.js .dart 18. Does Dart support comment? Yes, Dart supports comment. There are two types of comment: Single-line comments( // ) Multi-line comments ( /**/ ) 19. What are the various types of operators in Dart? In Dart, there are various types of operators: Arithmetic Operators Equality and Relational Operators Type test Operators Bitwise Operators Assignment Operators Logical Operators 20. What is the use of truncate methods? Truncate method is used to return an integer after discarding any fractions digits. Example: void main() { double n1 = 2.123; var value = n1.truncate(); print("The truncated value of 2.123 = "); } 21. What is the file extension of Dart? The file extension of Dart is .Dart. 22. What are the various methods to manipulate strings? There are various methods to manipulate string that are given in table: String Methods Description toLowerCase() It converts all the string character into lower case. toUpperCase() It converts all the string character into upper case. trim() It returns the string without any leading and trailing whitespace. compareTo() It compare objects to another objects. 23. Does Dart have syntax to declare interface? No, Class declarations are themselves interfaces in Dart. 24. What is the syntax to declare class? The following is the syntax to declare class. class class_name { } 25. How to create an example of this keyword in Dart? In Dart, the following code is used to create an example of this keyword. void main() { Car c1 = new Car('M2001'); } class Car { String engine; Car(String engine) { this.engine = engine; print("The engine is : "); } } 26. What are Getters and Setters in Dart? In Dart, Getters and Setters is also known as accessors and mutators. It allows the program to initialize and retrieve the values of class fields. 27. What is Method Overriding in Dart? In Dart, Method Overriding is a technique that child class redefines a method in its parent class. Example void main() { Child c = new Child(); c.m1(12); } class Parent { void m1(int a){ print("value of a ");} } class Child extends Parent { @override void m1(int b) { print("value of b "); } } 28. What is pub in Dart? In Dart, pub is a tool for manage Dart packages. 29. What is the syntax to handle an exception? The following syntax is used to handle an exceptions. try { // code that might throw an exception } on Exception1 { // code for handling exception } catch Exception2 { // code for handling exception } 30. Which editor is used to enables breakpoint and step by step debugging? WebStorm editor is used to enables breakpoint and step by step debugging. 31. What is typedef in Dart? In Dart, A typedef (Or function types alias) helps to define pointer to execute code within memory. Syntax: typedef function_name(parameters) Dart Programming Questions and Answers Pdf Download Read the full article
0 notes
jacob-cs · 8 years ago
Text
Android wear 개발 방법 (Syncing Data Items)
original source: https://developer.android.com/training/wearables/data-layer/data-items.html
Syncing Data Items
A DataItem defines the data interface that the system uses to synchronize data between handhelds and wearables.
Payload - A byte array, which you can set with whatever data you wish. 크기는  100kb
Path - A unique string that must start with a forward slash
normally don't implement DataItem directly. Instead, you do the following:
Create a PutDataRequest object, specifying a string path to uniquely identify the item.
Call setData() to set the payload.
If a delay in syncing would negatively impact user experience, call setUrgent().
Call DataApi.putDataItem() to request the system to create the data item.
Sync Data with a Data Map
use the DataMap class. This approach lets you work with data items in the form of an Android Bundle, so the system does object serialization and deserialization for you, and you can manipulate data with key-value pairs.
Create a PutDataMapRequest object, setting the path of the data item.
Call PutDataMapRequest.getDataMap() to obtain a data map that you can set values on.
Set any desired values for the data map using the put...() methods, such as putString().
If a delay in syncing would negatively impact user experience, call setUrgent().
Call PutDataMapRequest.asPutDataRequest() to obtain a PutDataRequest object.
Call DataApi.putDataItem() to request the system to create the data item.
Note: If the handset and wearable devices are disconnected, the data is buffered and synced when the connection is re-established.
ex)
public class MainActivity extends Activity implements        DataApi.DataListener,        GoogleApiClient.ConnectionCallbacks,        GoogleApiClient.OnConnectionFailedListener {    private static final String COUNT_KEY = "com.example.key.count";    private GoogleApiClient mGoogleApiClient;    private int count = 0;    ...    // Create a data map and put data in it    private void increaseCounter() {        PutDataMapRequest putDataMapReq = PutDataMapRequest.create("/count");        putDataMapReq.getDataMap().putInt(COUNT_KEY, count++);        PutDataRequest putDataReq = putDataMapReq.asPutDataRequest();        PendingResult<DataApi.DataItemResult> pendingResult =                Wearable.DataApi.putDataItem(mGoogleApiClient, putDataReq);    }    ... }
Set DataItem priority
In Google Play services 8.3 and later, the DataApi interface allows urgent requests for syncing of DataItems. setUrgent() 을 설정한다.
Listen for Data Item Events
public class MainActivity extends Activity implements        DataApi.DataListener,        GoogleApiClient.ConnectionCallbacks,        GoogleApiClient.OnConnectionFailedListener {    private static final String COUNT_KEY = "com.example.key.count";    private GoogleApiClient mGoogleApiClient;    private int count = 0;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        mGoogleApiClient = new GoogleApiClient.Builder(this)                .addApi(Wearable.API)                .addConnectionCallbacks(this)                .addOnConnectionFailedListener(this)                .build();    }    @Override    protected void onResume() {        super.onResume();        mGoogleApiClient.connect();    }    @Override    public void onConnected(Bundle bundle) {        Wearable.DataApi.addListener(mGoogleApiClient, this);    }    @Override    protected void onPause() {        super.onPause();        Wearable.DataApi.removeListener(mGoogleApiClient, this);        mGoogleApiClient.disconnect();    }    @Override    public void onDataChanged(DataEventBuffer dataEvents) {        for (DataEvent event : dataEvents) {            if (event.getType() == DataEvent.TYPE_CHANGED) {                // DataItem changed                DataItem item = event.getDataItem();                if (item.getUri().getPath().compareTo("/count") == 0) {                    DataMap dataMap = DataMapItem.fromDataItem(item).getDataMap();                    updateCount(dataMap.getInt(COUNT_KEY));                }            } else if (event.getType() == DataEvent.TYPE_DELETED) {                // DataItem deleted            }        }    }    // Our method to update the count    private void updateCount(int c) { ... }    ... }
1 note · View note
phpmentors · 8 years ago
Text
「現場で役立つシステム設計の原則」批判 (2) ~ポリモーフィズムは何のために?~
増田亨氏の「現場で役立つシステム設計の原則]」批判の第2編です。
(2)ポリモーフィズムは何のために?
オブジェクト指向の要件
本書には「変更を楽で安全にするオブジェクト指向の実践技法」というサブタイトルが付与されています。オブジェクト指向が何かという点については、論者によって違いはあるものの、以下の3つが要件とされることには、多くの人が合意するでしょう。
カプセル化
インヘリタンス(継承)
ポリモーフィズム(多態)
前回で明らかになったように、カプセル化は、オブジェクト指向とは独立にモジュール分割の指導原理としてデイビッド・パーナスにより提唱された「情報隠蔽」を敷衍したものです。オブジェクト指向の要件ではありますが、オブジェクト指向固有のアイデアではありません。
インヘリタンスは便利な機能ですが、コンポジションや移譲により代替できるので、オブジェクト指向の本質的な要件とは見做されなくなってきたかと思います。
となれば、プログラミングの歴史にオブジェクト指向が付け加えたものは、ポリモーフィズムであるということになります。オブジェクト指向のもっとも偉大な貢献は、イヌがワンと鳴き、ネコがニャーと鳴��ことです!
さて、こうした視点から本書を通読すると、まず、カプセル化については、その手段に過ぎない「データと処理を一体にする」という点に囚われ過ぎて、目的である「情報隠蔽」を取り逃がしているということが言えるかと思います。これが前回の指摘でした。
本書でのポリモーフィズム
では、本書ではポリモーフィズムはどのように扱われているでしょうか。
本書でポリモーフィズムを明示的に扱っているのは、「Chapter2 場合分けのロジックを整理する」だけです。この章でのポリモーフィズムの用途は、区分値に関する条件分岐(if文/switch文)を排除することです。
ポリモーフィズムのこうした利用方法は、マーティン・ファウラーのリファクタリング本で紹介され知られるようになったかと思いますが、便利でもあり、広く使われているものでもあると思います。
ただ、こうした「区分値ポリモーフィズム」は、ポリモーフィズムを適用可能なユースケース全体の中で、かなり周辺的なものであるように私には感じられます。その理由について以下ご説明します。
ポリモーフィズム ― 典型的な用法
その前にまず、ポリモーフィズムの典型的な用法とはどのようなものでしょうか。前回ご提示した、受注(SalesOrder)における値引き計算を例にご説明しましょう:
class SalesOrder { Money unitPrice; Quantity quantity; // ... Money amount() { if (isDiscountable()) return discount(unitPrice, quantity); return unitPrice.multiply(quantity); } // ... boolean isDiscountable() { return quantity.compareTo(discountCriteria) >= 0; } }
このコードでは、開示してよい知識と隠蔽したい知識を以下のように切り分け、前者をisDiscountable()に閉じ込めました:
開示してよい知識
受注ごとにその内容に応じて値引き可否が決まるという知識。
隠蔽したい知識
注文数量・金額等にもとづく具体的な値引き決定ルール。
ここで、「隠蔽したい知識」をなぜ隠蔽したいかというと、それが変わりやすいと考えるからです。ならば、一歩進んで、変わりやすい部分は差し替え可能にしておこうという発想が生まれます:
class SalesOrder { Money unitPrice; Quantity quantity; DiscountPolicy discountPolicy; // ... boolean isDiscountable() { return discountPolicy.isDiscountable(this); } }
ここで、DiscountPolicyは、以下のようなインターフェースです:
interface DiscountPolicy { boolean isDiscountable(SalesOrder salesOrder); }
DiscountPolicyの実装のひとつとして、QuantityBasedDiscountPolicyがあります:
class QuantityBasedDiscountPolicy implements DiscountPolicy { Quantity discountCriteria = Quantity.valueof(100); boolean isDiscountable(SalesOrder salesOrder) { return salesOrder.getQuantity().compareTo(discountCriteria) >= 0; } }
QuantityBasedDiscountPolicyは、たぶん、DIコンテナなどにより、SalesOrderのdiscountPolicyに注入されるでしょう。
この例で、ポリモーフィズムは、SalesOrderに関する様々な関心事から値引き計算に関する関心事を分離するのに用いられています。 例えば、テストという局面をとっても、QuantityBasedDiscountPolicyはSalesOrderに関する他のテストから切り離しでテストできますし、SalesOrderの方は(スタブを用いて)値引き計算の詳細を考慮せずにテストすることができます。 さらに、このソフトウェアが成功し、他社でも使われるようになれば、値引き計算ルールをこのように簡単にカスタマイズできることは、さらなるメリットをもたらすでしょう。
DiscountPolicyのように、特定の計算/判定条件をカプセル化し差替可能にするというポリモーフィズムの利用法は、GoFのデザインパターン本で「ストラテジー(別名:ポリシー)」として知られており、エリック・エバンスのドメイン駆動設計本でも、ごく最初の方で、オーバーブッキングポリシーという例が紹介されています(p.19/位置No.1068)。高度な利用法ではなく、極めて普通な用いられ方かと思います。
前回お話しした「情報隠蔽(=カプセル化)」では、隠蔽したい知識と開示してよい知識を区分して両者を別のモジュール(クラスもモジュールです)に割り振りました。 ポリモーフィズムは、そこから一歩進んで、それら2つのモジュールを切り離し、「疎結合化」するのに役立ちます。「疎結合」というと大げさに響きますが、要するに処理の依頼側と引受側2つのモジュールがあって、依頼側が引受側を知らずとも処理を依頼できるということです。この例で、値引き可否判定を依頼する側であるSalesOrderクラスはQuantityBasedDiscountPolicyクラスを知りません。
こういった意味における疎結合化は、オブジェクト指向以前も行われていましたが(*1)、気軽に、広範に適用できるようになったのは、やはりポリモーフィズムが生み出されてからのことです。
区分値ポリモーフィズムと本書に対する評価
さて、ポリモーフィズムの典型的なユースケースをおさらいした頭で、「区分値ポリモーフィズム」を見直してみましょう。
本書が説明する通り、区分値ポリモーフィズムには、if文やswitch文を排除することで、ソースコードの読みやすさを改善する機会を提供する、という役立ちがあります。
しかし、区分値オブジェクトのメソッド(本書の例では、yen()など)を呼び出す側のプログラムは、区分値オブジェクトのクラスを「知って」いるのが通常ですから、処理の依頼側と引受側は結合したままです(*2)。 ですから、前述したように「疎結合化」をポリモーフィズムの大きな意義と捉える立場からすれば、区分値ポリモーフィズムはやや傍流的な用法に見えることがお分かり頂けるでしょう。
公平に見て、本書は、ポリモーフィズムの他のユースケースについて触れていないだけであり、それらを否定しているわけではありません。ですから、本件は、本書の問題というより、読む側が注意すべき点である、ということなのかもしれません。
ただ、「多態は、区分ごとのロジックをクラス単位に分離してコードを読みやすくするオブジェクト指向らしいしくみです(p.58/位置No.1040)」といった説明を読む読者、とりわけオブジェクト指向の経験が浅い読者が、ポリモーフィズムの主な用途は区分ごとの場合分けロジックを整理することなのだと受け止めるのは自然なことでしょう。しかし、その道の先は行き止まりなのです。
むしろ、初級者には、疎結合化というビジョンのもとで、できるだけ簡単な入り口を示してあげるのが親切というものでしょう。上述したポリシーあるいはストラテジーパターンはそのような入り口として好適な例のひとつと思います。
「現場で役立つシステム設計の原則」という格調高いタイトルと「変更を楽で安全にするオブジェクト指向の実践技法」という具体的な副題を持つ300ページ超の本の中で、オブジェクト指向の業績の中心にあるポリモーフィズムについてこのように周辺的なユースケースのみ解説されている事態は、少なくとも私には驚異的なことです。
ポリモーフィズム ― さらなる展開
今回の批判はこれで終わりですが、例として取り上げた値引き計算のケースは、ポリモーフィズムの可能性を検討する上で興味深いので、もう少し深堀りしてみましょう。 前回以来の例では値引き可否判定ロジックの扱いが焦点でしたが、実際には可否を判定するだけでなく値引き額の計算が重要でしょう。業種にもよりますが、値引きの計算は複雑で、特定品目限定の値引き、過去の取引履歴に基づく値引き、一回の総発注額に基づく値引き、キャンペーンでの値引きなど多岐にわたるかもしれません。また、そうした値引きルールは、時の経過に応じて追加され、また廃止されていきます。システムは、そうした諸々の値引きについて、理由と金額をお客様に提示する必要があるでしょう。
こうした状��にどう対応すればよいでしょうか。SalesOrderクラスは、isDiscountable()メソッドで値引き可否だけを返せばよいのではなく、値引きの詳細を返さなければなりません。例えば、以下のようなメソッドを備えることになるでしょう:
List<Discount> getDiscounts();
Discountは、値引き理由の説明と値引き額を保持するオブジェクトです:
class Discount { String description; Money discount; // ... }
ここでの焦点は、値引きルールの詳細を隠蔽することに加えて、その時々に応じて値引きルールを追加し、あるいは廃止出来るようにすることです。それを踏まえれば、getDiscounts()の詳細は以下のようになるでしょう:
class SalesOrder { // DIコンテナなどから値引きポリシーのリストを設定 List<DiscountPolicy> discountPolicies; // ... List<Discount> getDiscounts() { List<Discount> discounts = new ArrayList<Discount>(); // 値引きポリシーを適用 for (DiscountPolicy discountPolicy : discountPolicies) { Discount discount = discountPolicy.getDiscountFor(this); if (discount != null) { discounts.add(discount); } } return discounts; } }
インターフェースDiscountPolicyは以下のようになります。
interface DiscountPolicy { /** * 与えられた salesOrder に対する値引きを計算し、その結果を Discount として返す。 * 当ポリシーでの値引きが salesOrder に適用されない場合は null を返す。 */ Discount getDiscountFor(SalesOrder salesOrder); }
このようにしておけば、新しい値引き制度が出来たときには、それに対応するDiscountPolicyを作成してシステムに登録するだけで対応が完了します(*3)。
値引き計算以外に、請求/回収条件、在庫引当、配送方法などにも同じような仕組みが適用可能かもしれません。こうした手法を常に適用すべきということではありませんが、適用しようと思えば出来る、ということを理解している��、設計における選択肢の幅が顕著に広がります。
こうした例をお示ししたのは、ポリモーフィズムというものが過度に技術的なものと受け止められているのではないかと私が危惧しているからです。
イヌがワンワン、ネコがニャーニャーという説明ばかりでポリモーフィズムはわからん、という方が多いですが、一方でその方もDIコンテナは使っていたりします。DIコンテナは、技術的環境に依存するオブジェクトに関して、アプリケーションにはインターフェースだけ提示し、その実装はポリモーフィズムによって実行時に結合することで、アプリケーションと技術的環境を疎結合に保つための仕掛けです。ポリモーフィズムのメカニズムが本当にわからないのであればDIコンテナを使うことさえ出来ないはずです。
ですから、多くの人にとってわからないのは、ポリモーフィズムのメカニズムではなく、「使いどころ」なのだろうと思うのです。フレームワークなどがポリモーフィズムを使っているのはわかっている。ただ、自分たちが書いている「アプリケーション」のコードにおいてどういう局面でポリモーフィズムを使えばよいのか、わからない。結果として、ポリモーフィズムは自分たちに関係ない「技術的」な概念だと感じてしまう。そういうことではないでしょうか。
実際には、それは誤解で、アプリケーション開発においてもポリモーフィズムはカジュアルに利用できます。値引き計算の例ではそれをご理解頂きたかったわけです。ポリシー(ストラテジー)パターンは、ポリモーフィズムのユースケースのごく一部に過ぎませんが、疎結合化というポリモーフィズムの本旨に沿っており、かつ、利用価値も高いものだと思います。
杉本 啓 @sugimoto_kei 経営管理基盤ソフトウェア fusion_place の、プログラマ兼設計者 http://www.fusions.co.jp
[脚注]
[1] 昔からある「ユーザ出口ルーチン」などはこの例でしょう。 [2] 料金計算など区分値に依存するメソッドを区分値クラスに移すことと、その計算にポリモーフィズムを適用することは別問題です。例えば本書p.60/位置No.1062のFeeTypeクラスは以下のように記述することもできます(label()に関する実装は省略)。
enum FeeType { ADULT, CHILD, SENIOR; Yen yen() { switch (this){ case ADULT: return adultFee(); case CHILD: return childFee(); case SENIOR: return seniorFee(); default: throw new UnsupportedOperationException("Fee for fee type [" + this + "] not defined."); } } private Yen adultFee() { return new Yen(100); } private Yen childFee() { return new Yen(50); } private Yen seniorFee() { return new Yen(80); } }
p.60/位置No.1062のコードとこのコードを比べてみると、料金計算方法という知識がFeeTypeクラスに隠蔽されている点は同じで、大人・子供・シニアの料金計算がそれぞれ別のメソッドに分離されている点も同じです。違いは、条件分岐に switch文を使うかポリモーフィズムを使うかという点だけです。 こうしたメソッドが複数あるならば、それぞれの実装でswitchを書くより、ポリモーフィズムを用いるべきでしょう。上記の例のようにswitchが1箇所だけであれば、いずれにするかは、設計の良否というより多分に好みの問題と、私は思います。
なお、このケースではそもそもポリモーフィズムを使うほどのこともなく、以下のコードで十分です。
enum FeeType { ADULT(100), CHILD(50), SENIOR(80); private final Yen yen; private FeeType(int yenAsInt) { this.yen = new Yen(yenAsInt); } Yen yen() { return yen; } }
ただ、これは、単にサンプルコードの選択に関する趣味の問題であって、区分値ポリモーフィズムの妥当性という論点には影響しません。
[3] ここで示したコード例は、値引き制度の間に相互依存関係がないという想定にもとづいています。依存関係があり得る場合(例えば上得意先向け値引きを適用したときにはキャンペーン値引きは適用しないといった条件に対応する場合)、DiscountPolicyにDiscountのリストを渡し、各ポリシーがそのリストに対してDiscountを除去したり追加したりできるようにする方がよいかもしれません。
interface DiscountPolicy { /** * 与えられた salesOrder に対する値引きを計算し、その結果を DiscountのListに追加する。 * リストから既存のDiscountを除去しても構わない。 */ void updateDiscounts(SalesOrder salesOrder, List<Discount> discounts); }
この場合、Discountに、値引き制度を識別するためのDiscountTypeなどを保持させることも必要でしょう。
値引き計算といった機能をこのように疎結合化するにあたり、疎結合化されたモジュール間の役割分担をどのように設計するかは極めて重要です。あるいはそれこそがオブジェクト指向にもとづくアプリケーション設計の核心部分かもしれません。 「オブジェクト指向」という言葉を作ったアラン・ケイは「オブジェクトよりもメッセージング」と強調したメールの中で、以下のように言っています:
The key in making great and growable systems is much more to design how its modules communicate rather than what their internal properties and behaviors should be.
(拙訳)偉大で成長可能なシステムを作る上でのカギは、個々のモジュールの内部特性や振る舞いがどうあるべきかということにではなく、むしろ、モジュールたちがどのようにコミュニケ―トするかをデザインすることにこそある。
また、「マルチパラダイムデザイン」で、ジム・コプリエンが提示した「共通性/可変性分析」も、こういった相互作用に重点を置いた設計手法です。
6 notes · View notes