Why are two references of Integer equal to a certain point? [duplicate] - java

This question already has answers here:
Using == operator in Java to compare wrapper objects
(8 answers)
Closed 7 years ago.
Why the Integer objects do not behave the way String objects behave?
I read that the reason was performance but can not understand how it would perform better?
Look at the code below for example :
public class MyClass{
public static void main(String[] args){
String one = "myString";
String two = "myString";
System.out.println(one == two); // true
String oneLong = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus in leo at massa vehicula rhoncus quis eu mauris. Pellentesque non nulla convallis, tempus augue sed, sollicitudin risus. Aenean posuere nulla ipsum, at faucibus massa dignissim non. Duis felis felis, iaculis eu posuere id, elementum id nulla. Fusce tristique arcu vitae consectetur vehicula. Mauris tincidunt nunc placerat tortor rhoncus, eget venenatis felis dapibus. Sed scelerisque ligula congue ligula elementum hendrerit. Proin et mauris vestibulum, rutrum ante ut, sollicitudin massa. Fusce tempus mattis eleifend. Phasellus ut ante turpis. Suspendisse eu leo nec elit ornare rhoncus sed nec ex. In at tellus mi.";
String twoLong = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus in leo at massa vehicula rhoncus quis eu mauris. Pellentesque non nulla convallis, tempus augue sed, sollicitudin risus. Aenean posuere nulla ipsum, at faucibus massa dignissim non. Duis felis felis, iaculis eu posuere id, elementum id nulla. Fusce tristique arcu vitae consectetur vehicula. Mauris tincidunt nunc placerat tortor rhoncus, eget venenatis felis dapibus. Sed scelerisque ligula congue ligula elementum hendrerit. Proin et mauris vestibulum, rutrum ante ut, sollicitudin massa. Fusce tempus mattis eleifend. Phasellus ut ante turpis. Suspendisse eu leo nec elit ornare rhoncus sed nec ex. In at tellus mi.";
System.out.println(oneLong == twoLong); // true
Integer first = 1;
Integer second = 1;
System.out.println(first == second); // true
Integer third = 500;
Integer fourth = 500;
System.out.println(third == fourth); // false
}
}
Here are the questions I found but no response was given there :
Why Integer In Java is Immutable
Is Integer Immutable?

Generally is a good idea to mantain an object as immutable as possible because an immutable object can be shared without problems in a multithreading enviroment.
Creating n copies of the same Integer is possible, ma that copies are immutable. Note that also for String is possible to create n different copies of the same String. To do that you need to explicitly use the new keyword.
Two objects are the same if compared with the operator == returns true. Two objects have the same content if compared with the method equals returns true.
obj1 == obj2 // if true obj1 and obj2 are the same
obj1.equals(obj2) // if true obj1 and obj2 have the same content
// (can be the same or not)
In your example you have two Integer with the same content (so equals returns true) but different memory locations (so == returns false)

Related

Java libraries that facilitate "stitching" together multiple multi-line strings

I am trying to stitch together multiple multi-line strings together to create the effect of several columns of text. Consider the three text blocks below:
Lorem ipsum dolor si
t amet, consectetur
adipiscing elit, sed
do eiusmod tempor in
cididunt ut labore e
t dolore magna aliqu
a.
Volutpat consequat m
auris nunc congue ni
si vitae. Sed risus
ultricies tristique
nulla aliquet enim t
ortor at auctor.
Urna porttitor rhonc
us dolor purus non.
Interdum varius sit
amet mattis vulputat
e enim nulla.
The block width is fixed at 20 characters. Ignore the wrapping of words.
What I want to do is stitch or append these separate multi-line strings together to produce the following:
Lorem ipsum dolor si Volutpat consequat m Urna porttitor rhonc
t amet, consectetur auris nunc congue ni us dolor purus non.
adipiscing elit, sed si vitae. Sed risus Interdum varius sit
do eiusmod tempor in ultricies tristique amet mattis vulputat
cididunt ut labore e nulla aliquet enim t e enim nulla.
t dolore magna aliqu ortor at auctor.
a.
In this case, the column spacing is 4 characters wide.
Is anyone aware of a Java library or utility that facilitates this? If not implemented in Java, is there anything that could do this, that could be invoked from Java code?

Check if one List<String> contains specific string from another list

I have a List<String> emails containing emails, of length n , and another List<String> keywords for containing keywords, of the same length. These lists should meet following condition: For each index i emails.get(i).contains(keywords.get(i))
So, if emails.get(0) == "quick brown fox", then keywords.get(0) == "fox".
if emails.get(5) == "foo bar", then keywords.get(5) == "foo".
How can I check (other than for loop) that each email contains a keyword?
First, it may be needed to check the size of both lists, then to compare corresponding list items, IntStream should be used:
public static boolean allKeywordsFound(List<String> emails, List<String> keywords) {
return emails.size() == keywords.size() &&
IntStream.range(0, emails.size())
.allMatch(i -> emails.get(i).contains(keywords.get(i)));
}
I see that others correctly answered your question but here's my take on the issue.
I presume you want the emails to be checked in order so here's a piece of code that uses Stream API instead of a for loop, I also put together the emails list and the result into a Map since you didn't specify whether you want the resulting boolean value to be for all the emails together or if you want a boolean value for each email containing the same-position keyword:
//mock data initialization
List<String> emails = new ArrayList<>();
List<String> keywords = new ArrayList<>();
//mock data initialization
emails.add("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua");
emails.add("eu lobortis elementum nibh tellus molestie nunc non blandit massa enim nec dui nunc mattis enim ut tellus elementum sagittis");
emails.add("Dignissim suspendisse in est ante in nibh mauris");
//mock data initialization
keywords.add("consectetur");
keywords.add("Foo");
keywords.add("Dignissim");
//initialized a list to contain whether a keyword exists for each email
List<Boolean> exists = new ArrayList<>();
//loaded it with boolean values (the exists List has the same order as the emails list)
emails.forEach(email -> exists.add(email
.contains(keywords
.get(emails
.indexOf(email)))));
//since I don't know what you wanna do with the result, I decided to just put them together in a Map
//with the email string as the key and the existence variable as a value
LinkedHashMap mapOfTruth = new LinkedHashMap();
emails.forEach(email -> mapOfTruth.put(email, exists.get(emails.indexOf(email))));
Output
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua = true
eu lobortis elementum nibh tellus molestie nunc non blandit massa enim nec dui nunc mattis enim ut tellus elementum sagittis = false
Dignissim suspendisse in est ante in nibh mauris = true
This code using Java streams/maps checks if each email contains their respective keyword.
boolean allEmailsContainKeyword(List<String> emails, List<String> keywords) {
return !emails.stream().map(email -> email.contains(keywords.get(emails.indexOf(email)))).collect(Collectors.toList()).contains(false);
}

canvas incorrectly draws heights cell in table itext7

i draw table as it: Draw custom borders for table with more flexibility in itext7
But i But with big data the table is badly drawn height cell in table.
PdfDocument pdfDoc = new PdfDocument(new PdfWriter("_testPd/dashed_underline.pdf"));
Document doc = new Document(pdfDoc, PageSize.A5);
Table table = new Table(3).useAllAvailableWidth().setFixedLayout();
table.addCell("Highway System that runs east from the Indiana state line near Lake Michigan through the southern Lower Peninsula to Detroit, then n");
table.addCell("Highway System that runs east from the Indiana state line near Lake Michigan through the southern Lower Peninsula to Detroit, then n");
table.addCell("Highway System that runs east from the Indiana state line near Lake Michigan through the southern Lower Peninsula to Detroit, then n");
table.addCell("Pell morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo. Quisque sit amet est et sapien ullamcorper pharetra. Vestibulum erat wisi, condimentum sed, commodo vitae, ornare sit amet, wisi. Aenean fermentum, elit eget tincidunt condimentum, eros ipsum rutrum orci, sagittis tempus lacus enim ac dui. Donec non enim in turpis pulvinar facilisis. Ut felis. Praesent dapibus, neque id cursus faucibus, tortor neque egestas augue, eu vulputate magna eros eu erat. Aliquam erat volutpat. Nam dui mi, tincidunt quis, accumsan porttitor, facilisis luctus, metus");
table.setNextRenderer(new CustomTableRenderer(table));
doc.add(table);
doc.close();
also one example:
Table table = new Table(3);
table.addCell("hello1 ");
table.addCell("hello2 ");
table.addCell("hello3 ");
table.addCell("hello4\nWord ");
table.addCell("hello5 ");
There is a minor mistake in your custom renderer: the items of heights list represent rows from the highest to the lowest, but you're drawing the borders from the lowest to the highest.
The following code should be used to draw horizontal lines:
// Draw horizontal lines
float curY = getOccupiedAreaBBox().getTop();
for (int i = 0; i <= heights.size(); i++) {
canvas.moveTo(getOccupiedAreaBBox().getLeft() - 3, curY);
canvas.lineTo(getOccupiedAreaBBox().getRight() + 3, curY + r.nextInt(4));
if (i < heights.size()) {
float curHeight = heights.get(i);
curY -= curHeight;
}
}

How to match any word but ignore those that starts with multiple whitespaces?

What I am trying to achieve is to match all words in text, but ignore those words in line (before new line) that start with 4 whitespaces.
Example
Text file to find words:
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut
enim ad minim veniam, quis nostrud exercitation ullamco laboris
nisi ut aliquip ex ea commodo consequat.
This must NOT be matched. Because it has 4 whitespaces at the beginning.
Lorem ipsum dolor sit amet. Ut enim ad minim veniam.
So, the words in following line should be NOT considered to match pattern:
This must NOT be matched. Because it has 4 whitespaces at the beginning.
Code
Here is my regex and it can find all words:
\\b[A-Za-z]+\\b
I know that in Java's RegEx syntax there is except which is ^ symbol but I only know how to use it in more simple expressions.
Maybe following snippet could be a basis for what you want to achieve.
String[] lines = {"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do",
"eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut",
"enim ad minim veniam, quis nostrud exercitation ullamco laboris",
"nisi ut aliquip ex ea commodo consequat.",
"",
" This must NOT be matched. Because it has 4 whitespaces at the beginning.",
"",
"Lorem ipsum dolor sit amet. Ut enim ad minim veniam."};
for (String line : lines) {
if (!line.startsWith(" ")) {
String[] words = line.split("[\\p{IsPunctuation}\\p{IsWhite_Space}]+");
System.out.println("words = " + Arrays.toString(words));
}
}
output
words = [Lorem, ipsum, dolor, sit, amet, consectetur, adipiscing, elit, sed, do]
words = [eiusmod, tempor, incididunt, ut, labore, et, dolore, magna, aliqua, Ut]
words = [enim, ad, minim, veniam, quis, nostrud, exercitation, ullamco, laboris]
words = [nisi, ut, aliquip, ex, ea, commodo, consequat]
words = []
words = []
words = [Lorem, ipsum, dolor, sit, amet, Ut, enim, ad, minim, veniam]
PS: the regex has been borrowed from this answer
The following should do that
(?<!\s{4})\\b[A-Za-z]+\\b
It begins with a negative lookbehind so it won't match anything with \s{4} preceding it.

regex VS Contains. Best Performance? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 4 years ago.
Improve this question
I want to compare an URI String over different patterns in java and I want fastest code possible.
Should I use :
if(uri.contains("/br/fab") || uri.contains("/br/err") || uri.contains("/br/sts")
Or something like :
if(uri.matches(".*/br/(fab|err|sts).*"))
Note that I can have a lot more uri and this method is called very often.
What is the best answer between my choices ?
If you're going to use a regular expression, create it up-front and reuse the same Pattern object:
private static final Pattern pattern = Pattern.compile(".*/br/(fab|err|sts).*");
Do you actually need the ".*" at each end? I wouldn't expect it to be required, if you use Matcher.find().
Which is faster? The easiest way to find out is to measure it against some sample data - with as realistic samples as possible. (The fastest solution may very well depend on
Are you already sure this is a bottleneck though? If you've already measured the code enough to find out that it's a bottleneck, I'm surprised you haven't just tried both already. If you haven't verified that it's a problem, that's the first thing to do before worrying about the "fastest code possible".
If it's not a bottleneck, I would personally opt for the non-regex version unless you're a regex junkie. Regular expressions are very powerful, but also very easy to get wrong.
I've done a test and it is faster to use contains. As Ewan Todd said, they both fast enough to don't really bother with that.
Both are fast enough, but contains is faster. Facts: ~20mil ops vs ~1mil ops
Using the following jmh code to test
#State(Scope.Benchmark)
public class Main {
private String uri = "https://google.com/asdfasdf/ptyojty/aeryethtr";
#Benchmark
#Warmup(iterations = 5)
#Measurement(iterations = 5)
#Fork(value = 1, warmups = 0)
public void initContains() throws InterruptedException {
if (uri.contains("/br/fab") || uri.contains("/br/err") || uri.contains("/br/sts")) {}
}
#Benchmark
#Warmup(iterations = 5)
#Measurement(iterations = 5)
#Fork(value = 1, warmups = 0)
public void initMatches() throws InterruptedException {
if (uri.matches(".*/br/(fab|err|sts).*")) {}
}
public static void main(String[] args) throws Exception {
org.openjdk.jmh.Main.main(args);
}
}
The results
# Run complete. Total time: 00:00:37
Benchmark Mode Cnt Score Error Units
Main.initContains thrpt 5 21004897.968 ± 1987176.746 ops/s
Main.initMatches thrpt 5 1177562.581 ± 248488.092 ops/s
I would expect contains() to be faster since it won't have to compile and iterate through a (relatively) complex regular expression, but rather simply look for a sequence of characters.
But (as with all optimisations) you should measure this. Your particular situation may impact results, to a greater or lesser degree.
Furthermore, is this known to be causing you grief (wrt. performance) ? If not, I wouldn't worry about it too much, and choose the most appropriate solution for your requirements regardless of performance issues. Premature optimisation will cause you an inordinate amount of grief if you let it!
UPDATE:
I know this is not the best benchmark code and for each case there are several ways to optimize it.
What I wanted to achieve was, for a regular developer that will use the simpler ways of doing things and it's not a JVM expert, that's the "common" way to use it, so here it goes.
ORIGINAL:
The below code produced the following output
contains took: 70
matches took: 113
matches with pre pattern took: 419
The test class
public class MatchesTester {
public static void main(String[] args) {
String typeStr = "Nunc rhoncus odio ac tellus pulvinar, et volutpat sapien aliquet. Nam sed libero nec ex laoreet pretium sed id mi. Aliquam erat volutpat. Aenean at erat vitae massa iaculis mattis. Quisque sagittis massa orci, sit amet vestibulum turpis tempor a. Etiam eget venenatis arcu. Nunc enim augue, pulvinar at nulla ut, pellentesque porta sapien. Maecenas ut erat id nisi tincidunt faucibus eget vel erat. Morbi quis magna et massa pharetra venenatis ut a lacus. Vivamus egestas vitae nulla eget tristique. Praesent consectetur, tellus quis bibendum suscipit, nisl turpis mattis sapien, ultrices mollis leo quam eu eros.application/binaryNunc rhoncus odio ac tellus pulvinar, et volutpat sapien aliquet. Nam sed libero nec ex laoreet pretium sed id mi. Aliquam erat volutpat. Aenean at erat vitae massa iaculis mattis. Quisque sagittis massa orci, sit amet vestibulum turpis tempor a. Etiam eget venenatis arcu. Nunc enim augue, pulvinar at nulla ut, pellentesque porta sapien. Maecenas ut erat id nisi tincidunt faucibus eget vel erat. Morbi quis magna et massa pharetra venenatis ut a lacus. Vivamus egestas vitae nulla eget tristique. Praesent consectetur, tellus quis bibendum suscipit, nisl turpis mattis sapien, ultrices mollis leo quam eu eros.";
int timesToTest = 10000;
long start = System.currentTimeMillis();
int count = 0;
//test contains
while(count < timesToTest){
if (typeStr.contains("image") || typeStr.contains("audio") || typeStr.contains("video") || typeStr.contains("application")) {
//do something non expensive like creating a simple native var
int a = 10;
}
count++;
}
long end = System.currentTimeMillis();
System.out.println("contains took: "+ (end - start));
long start2 = System.currentTimeMillis();
count = 0;
while(count < timesToTest){
if (typeStr.matches("(image|audio|video|application)")) {
//do something non expensive like creating a simple native var
int a = 10;
}
count++;
}
long end2 = System.currentTimeMillis(); //new var to have the same cost as contains
System.out.println("matches took: "+ (end2 - start2));
long start3 = System.currentTimeMillis();
count = 0;
Pattern pattern = Pattern.compile("(image|audio|video|application)");
while(count < timesToTest){
if (pattern.matcher(typeStr).find()) {
//do something non expensive like creating a simple native var
int a = 10;
}
count++;
}
long end3 = System.currentTimeMillis(); //new var to have the same cost as contains
System.out.println("matches with pre pattern took: "+ (end3 - start3));
}
If the bit you are trying to match against is always at the beginning, or end, or is in some other way predictable then: neither!
For example, if urls are like http://example.com/br/fab or http://example.com/br/err all the time, then you could store "br/fab" and "br/err" etc in a HashSet or similar, and then given an incoming URL, chop off the last part of it and query the Set to see if it contains it. This will scale better than either method you gave (with a HashSet it should get no slower to lookup entries no matter how many there are).
If you do need to match against substrings appearing in arbitrary locations... it depends what you mean by "a lot more". One thing you should do regardless of the specifics of the problem is try things out and benchmark them!
its much faster if you use indexOf().
if(uri.indexOf("/br/fab")>-1 || uri.indexOf("/br/err")>-1 || uri.indexOf("/br/sts") >-1 )
{
your code.
}
and problem with contains() is internally it creates a Matcher(java.util.regex.Matcher) object and evalates the expression.
Matcher is a very costly thing if processing large amount of data.
They're both fast enough to be over before you know it. I'd go for the one that you can read more easily.

Categories