Need to print top three values in console - java

I just found elements (around 100 float values) via XPath and printed them on console using System.Out.. Now I need to sort them and print top three values from them. Please help me in this regard.
Thanks

I dont know about selenium, My code is related to java. If your float number are strings like this (5.3 6.366), You can use below code:
String floatNumber = "5.3 6.366";
String[] numbers = floatNumber.split(" ");
Arrays.sort(numbers);
for(int i=0; i<numbers.length;i++){
System.out.println(numbers[i]);
}

Since yo are using SeleniumWebdriver, you probably have this as a data structure: List<WebElement>.
Lists are part of the java.util.Collection framework and therefore it is not very hard to implement a sorting. Something like this could work, if list contains the List<WebElement> and the float values that you want to sort after are in an attribute called toSortAfter:
Collections.sort(list, new Comparator<WebElement>(){
#Override
public int compare(WebElement e1, WebElement e2){
String fl1Str = e1.getAttribute("toSortAfter");
String fl2Str = e2.getAttribute("toSortAfter");
if (fl1Str != null && fl2Str != null){
float f1 = Float.parseFloat(fl1Str);
float f2 = Float.parseFloat(fl2Str);
if (f1 < f2){
return -1;
}
else if (f1 > f2) {
return 1;
}
}
return 0;
}
});
I leave better handling of Exceptions to the interested reader... Also, note that I wrote this out of my head and without a Java-Compiler at hand. So there might be syntax or other mistakes.
Note:
Without the knowledge of the HMTL nodes you are collectiong it is not possible to help you any further. It might be, that the attribute is called differently, of that the float value is not an attribute altogether. If is it the content of the Elements, you can access this with WebElement.getText() method.

Related

Is it possible to stream double values from an array using scanner?

I have a method that needs single values as the input, but I only have the information in an array. I have searched and found out that Scanner can stream values but only in string form. So I thought I should change the array into string and then convert it back into double before returning the value.
Here is what I had written.
double E;
public double StreamValue (double[]g2){
Scanner s = new Scanner(Arrays.toString(g2)); //PROBLEM HERE
while (s.hasNext()){
E = Double.parseDouble(s.next());
}
return E;
}
When I ran the code, it failed. My question is, is the idea right but I'm missing any part, or it's completely invalid?
Edited:
I need to feed the streaming values into a methode that will analyze each values and return an int.
This is kind of a short example of it:
public int EventAnalyzer(double E) {
if (E > c_max)
a = 0;
else
a = 1;
return a;
}
The returned value will be used for this method:
private void isDetected (int a){
CharSequence t0 = "No breathing";
CharSequence t1 = "Normal breathing";
TextView textView = (TextView)findViewById(R.id.apnea);
if(a==0)
textView.setText(t0);
if(a==1)
textView.setText(t1);
}
I think, your idea is right.
But your result E must be an array of double:
double[] E;
Your goal is not completely clear to me, but
if you have double[] g2:
You can use an enhanced for-loop:
for(double d : g2)
System.out.println("This is a double from array: "+ d);
If you need to return one double from the array, then you can retrieve it using the index by doing
return g2[x];
where x is a valid index between 0 and g2.length - 1.
#Alexander Anikin had answered the question in the comment. I'm working on the Arrays.stream but it requires API 24 while I have API 19. I'm looking for other way possible. Thanks everyone for the responses!

program on arraylist java

System.out.println("Enter the appointment ID to see the full details :");
int y=in.nextInt();
int r;
for(r=0;r<count;r++)
{
if(all.get(r).getID()==y)
{
all.get(r).display();
}
}
I am using this code to retrieve the full details that have been entered using the get statement and display function. This is a small part of my program. I was wondering is there any other way to do it
A better way would be to use a HashMap<Integer,DetailsClass> instead of an ArrayList.
Then, instead of a loop, you'll just write :
HashMap<Integer,DetailsClass> map = new HashMap<>();
...
if (map.containsKey(y)) {
DetailsClass details = map.get(y);
details.display();
}
This makes the code simpler and more efficient, since searching for a key in a HashMap takes expected constant time, while searching the List takes linear time.
If you must use an ArrayList, at least leave the loop once you find the object you were looking for :
int y=in.nextInt();
for(int r=0;r<count;r++)
{
if(all.get(r).getID()==y)
{
all.get(r).display();
return; // or break; depending on where this for loop is located
}
}
Never loop over a List by index. You don't know what the internal implementation of the List is and looping might result on O(n^2) complexity.
I would suggest the following:
System.out.println("Enter the appointment ID to see the full details :");
final int y = in.nextInt();
for(final Thing thing : all) {
if(thing.getID() == y) {
thing.display();
}
}
Or, if you can use Java 8, then:
all.stream()
.filter(t -> t.getID() == y)
.findFirst()
.ifPresent(Thing::display);

What is better/faster in Java: 2 method calls or 1 object call

I'm afraid this is a terribly stupid question. However, I can't find an answer to it and therefore require some help :)
Let's start with a simplification of my real problem:
Assume I have a couple of boxes each filled with a mix of different gems.
I'm now creating an object gem which has the attribute colour and a method getColour to get the colour of the gem.
Further I'm creating an object box which has a list of gems as attribute and a method getGem to get a gem from that list.
What I want to do now is to count all gems in all boxes by colour. Now I could either do something like
int sapphire = 0;
int ruby = 0;
int emerald = 0;
for(each box = i)
for(each gem = j)
if(i.getGem(j).getColour().equals(“blue”)) sapphire++;
else if(i.getGem(j).getColour().equals(“red”)) ruby++;
else if(i.getGem(j).getColour().equals(“green”)) emerald++;
or I could do
int sapphire = 0;
int ruby = 0;
int emerald = 0;
String colour;
for(each box = i)
for(each gem = j)
colour = i.getGem(j).getColour();
if(colour.equals(“blue”)) sapphire++;
else if(colour.equals(“red”)) ruby++;
else if(colour.equals(“green”)) emerald++;
My question is now if both is essentially the same or should one be preferred over the other? I understand that a lot of unnecessary new string objects are produced in the second case, but do I get a speed advantage in return as colour is more “directly” available?
I would dare to make a third improvement:
int sapphire = 0;
int ruby = 0;
int emerald = 0;
for(each box = i) {
for(each gem = j) {
String colour = i.getGem(j).getColour();
if(“blue”.equals(colour)) sapphire++;
else if(“red”.equals(colour)) ruby++;
else if(“green”.equals(colour)) emerald++;
}
}
I use a local variable inside the for-loop. Why? Because you probably need it only there.
It is generally better to put STATIC_STRING.equals(POSSIBLE_NULL_VALUE).
This has the advantage: easier to read and should have no performance problem. If you have a performance problem, then you should consider looking somewhere else in your code. Related to this: this answer.
conceptually both codes have equal complexity i.e.: O(i*j). But if calling a method and get a returned value are considered to be two processes then the complexity of your first code will be 4*O(i*j).(consider O(i*j) as a function) and of your second code will be O(i*(j+2)). although this complexity difference is not considerable enough but if you are comparing then yes your first code is more complex and not a good programming style.
The cost of your string comparisons is going to wipe out all other considerations in this sort of approach.
You would be better off using something else (for example an enum). That would also expand automatically.
(Although your for each loop isn't proper Java syntax anyway so that's a bit odd).
enum GemColour {
blue,
red,
green
}
Then in your count function:
Map<GemColour, Integer> counts = new EnumMap<GemColour, Integer>(GemColour.class);
for (Box b: box) {
for (Gem g: box.getGems() {
Integer count = counts.get(g.getColour());
if (count == null) {
count=1;
} else {
count+=1;
}
counts.put(g.getColour(), count);
}
}
Now it will automatically extend to any new colors you add without you needing to make any code changes. It will also be much faster as it does a single integer comparison rather than a string comparison and uses that to put the correct value into the correct place in the map (which behind the scenes is just an array).
To get the counts just do, for example:
counts.get(GemColour.blue);
As has been pointed out in the comments the java Stream API would allow you to do all of this in one line:
boxes.stream().map(Box::getGems).flatMap(Collection::stream).collect(groupingBy‌​‌​(Gem::getColour, counting()))
It's less easy to understand what it is doing that way though.

Java - Sort an Array Twice?

I am working on a program that displays zip codes and house numbers. I need to sort the zip codes in ascending order in the first column then sort the house numbers from left to right, keeping them with the same zip code.
For instance:
Looks like this:
90153 | 9810 6037 8761 1126 9792 4070
90361 | 2274 6800 2196 3158 9614 9086
I want it to look like this:
90153 | 1126 4070 6037 8761 9792 9810
90361 | 2186 2274 3158 6800 9086 9614
I used the following code to sort the zip codes but how do I sort the house numbers? Do I need to add a loop to sort the numbers to this code? If so, where? So sorry I couldn't make the code indent correctly.
void DoubleArraySort()
{
int k,m,Hide;
boolean DidISwap;
DidISwap = true;
while (DidISwap)
{
DidISwap = false;
for ( k = 0; k < Row - 1; k++)
{
if ( Numbers[k][0] > Numbers[k+1][0] )
{
for ( m = 0; m < Col; m++)
{
Hide = Numbers[k ][m];
Numbers[k ][m] = Numbers[k+1][m];
Numbers[k+1][m] = Hide ;
DidISwap = true;
}
}
}
}
}
Use an object ZipCode like this:
public class ZipCode{
private String zipcode;
private ArrayList<String> adds
public ZipCode(String zip){
zipcode = zip;
adds = new ArrayList<String>();
}
public void addAddress(String address){
adds.add(address);
Collections.sort(adds);
}
}
Keep an array of ZipCodes sorting them necessarily:
ZipCode[] zips = . . .
.
.
.
Arrays.sort(zips);
First of all, are you aware that Java provides a more efficient sorting mechanism out of the box? Check the Arrays class.
Secondly you have to be very careful with your approach. What you are doing here is swapping all the elements of one row with the other. But you are not doing the same thing within each row. So you need a separate nested loop outside the current while (before or after, doesn't make a difference), which checks the houses themselves and sorts them:
for ( k = 0; k < Row; k++)
{
do
{
DidISwap = false;
for ( m = 0; m < Col-1; m++)
{
if (Numbers[k][m] > Numbers[k][m+1])
{
Hide = Numbers[k][m];
Numbers[k][m] = Numbers[k][m+1];
Numbers[k][m+1] = Hide;
DidISwap = true;
}
}
}
while (DidISwap);
}
However, your approach is very inefficient. Why don't you put the list of houses in a SortedSet, and then create a SortedMap which maps from your postcodes to your Sorted Sets of houses? Everything will be sorted automatically and much more efficiently.
You can use the TreeMap for your SortedMap implementation and the TreeSet for your SortedSet implementation.
I / we could try to tell you how to fix (sort of) your code to do what you want, but it would be counter-productive. Instead, I'm going to explain "the Java way" of doing these things, which (if you follow it) will make you more productive, and make your code more maintainable.
Follow the Java style conventions. In particular, the identifier conventions. Method names and variable names should always start with a lower case character. (And try to use class, method and variable names that hint as to the meaning of the class/method/variable.)
Learn the Java APIs and use existing standard library classes and methods in preference to reinventing the wheel. For instance:
The Arrays and Collections classes have standard methods for sorting arrays and collections.
There are collection types that implement sets and mappings and the like that can take care of "boring" things like keeping elements in order.
If you have a complicated data structure, build it out of existing collection types and custom classes. Don't try and represent it as arrays of numbers. Successful Java programmers use high-level design and implementation abstractions. Your approach is like trying to build a multi-storey car-park from hand-made bricks.
My advice would be to get a text book on object-oriented programming (in Java) and get your head around the right way to design and write Java programs. Investing the effort now will make you more productive.

Java string comparison

I am comparing substrings in two large text files. Very simple, tokenizing into two token containers, comparing with 2 for loops. Performance is disastrous! Does anybody have an advice or idea how to improve performance?
for (int s = 0; s < txtA.TokenContainer.size(); s++) {
String strTxtA = txtA.getSubStr(s);
strLengthA = txtA.getNumToken(s);
if (strLengthA >= dp.getMinStrLength()) {
int tokenFileB = 1;
for (int t = 0; t < txtB.TokenContainer.size(); t++) {
String strTxtB = txtB.getSubStr(t);
strLengthB = txtB.getNumToken(t);
if (strTxtA.equalsIgnoreCase(strTxtB)) {
try {
subStrTemp = new SubStrTemp(
txtA.ID, txtB.ID, tokenFileA, tokenFileB,
(tokenFileA + strLengthA - 1),
(tokenFileB + strLengthB - 1));
if (subStrContainer.contains(subStrTemp) == false) {
subStrContainer.addElement(subStrTemp);
}
} catch (Exception ex) {
logger.error("error");
}
}
tokenFileB += strLengthB;
}
tokenFileA += strLengthA;
}
}
Generally my code reading two large Strings with Java Tokonizer into containers A and B. And then trying to compare substrings.Possision of Substrgs which are existing in both strings to store into a Vector. But performance is awful, also don't really know how to solve it with HashMap.
Your main problem is that you go through all txtB for each token in txtA.
You should store informations on token from txtA (in a HashMap for instance) and then in a second loop (but not a nested one) you compare the strings with the existing one in the Map.
On the same topic :
term frequency using java program
How to count words in java
You are doing a join with nested loops? Yes, that is O(n^2). What about doing a hash join instead? That is, create a map from (lowercased) strText to t and do lookups with this map rather than iterating over the token container?
Put the tokens of fileA into a trie data structure. Then when tokenising fileB you can check quite quickly if these tokens are in the trie. A few code comments would help.
A said, this is an issue of complexity and you're algorithm runs in O(n^2) instead of O(n) using hash.
For second order improvements try to call less to functions, for example you can get the size once
sizeB = txtB.TokenContainer.size();
Depeneds on the size, you may call the container once to get an array of strings to save the getStr....
Roni

Categories

Resources