I'm trying to get highest price of a product. I'm able to store the prices in an object.
I want to know how to get the maximum value from that object. Below is my code!
public class amazon {
static WebDriver driver;
public static void main(String[] args) throws Exception {
System.setProperty("webdriver.chrome.driver", "C://Selenium/chromedriver.exe");
driver = new ChromeDriver();
driver.get("xyzzz.com");
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
amazon az = new amazon();
az.run();
}
public void run() throws Exception {
List<Object> obj = new ArrayList<Object>();
List<WebElement> tag = driver.findElements(By.xpath("//span[#class='a-price-whole']"));
int i;
for(i=0; i<tag.size(); i++) {
obj.add(tag.get(i).getText());
}
System.out.println(obj);
driver.close();
}
Output i have..
[64,900, 99,900, 1,23,900, 64,900, 64,900, 69,900, 64,900, 64,900, 1,23,900, 52,900]
You first need to convert the numbers to int, and than you can use Collections.max on the list
List<Integer> prices = new ArrayList<>();
List<WebElement> tags = driver.findElements(By.xpath("//span[#class='a-price-whole']"));
for (WebElement tag: tags) {
prices.add(Integer.parseInt(tag.getText().replace(",", "")));
}
System.out.print(Collections.max(prices)); // 123900
Map the strings to ints (or longs, or some type of currency), then you can get the max using a Comparator
int max = driver.findElements(By.xpath("//span[#class='a-price-whole']")).stream()
.map(WebElement::getText)
.map(s -> s.replace(",", ""))
.map(Integer::parseInt)
.max(Integer::compare)
.get();
create an int and call it max (=0), run on each element of the list using a loop (for loop recommended), on each element, check if its bigger than max, if yes, put the value in max,
here is a little code, in case the list is called "list", change it to whatever you want
int max=0;
for (int i : list){
if (i >max)
max=i;
}
System.out.println(max) //print the maximum value of the array
Related
I am a beginner in java. I want to read elements one by one in sublist.
public class ListFirst {
public static void main(String[] args) {
List<Integer>list1= Arrays.asList(10,20,30,40);
List<Integer>list2=Arrays.asList(100,200,300,400);
List<List<Integer>>bigList= new ArrayList<>();
// I want to access an element of bigList one by one. how to do that?
}
}
If there is no sublist I can print using for loop upto list.size() and list.get() to print but here element is list itself..so I dont know how to read. could you please help me with that.
I modified your code to achieve what you wanted to do:
public class ListFirst {
public static void main(String[] args) {
List<Integer>list1= Arrays.asList(10,20,30,40);
List<Integer>list2=Arrays.asList(100,200,300,400);
List<List<Integer>>bigList= new ArrayList<>();
bigList.add(list1);
bigList.add(list2);
for (List<Integer> list : bigList) {
for (Integer i : list) {
System.out.print(i.intValue() + " ");
}
}
}
}
An alternative would be to not use nested List for storing your Integers:
public static void main(String[] args) {
List<Integer>list1= Arrays.asList(10,20,30,40);
List<Integer>list2=Arrays.asList(100,200,300,400);
// bigList is a list of Integers not list of lists
List<Integer>bigList= new ArrayList<>();
bigList.addAll(list1); // add all elements from list1
bigList.addAll(list2); // add all elements from list2
for (Integer i : bigList) {
System.out.print(i.intValue() + " ");
}
}
Assuming that the lists have bee added to bigList, you can iterate it using the for-each loop as shown below:
bigList.add(list1);
bigList.add(list2);
for (List<Integer> list : bigList) {
System.out.println(list);
}
DEMO
Using the traditional loop, you can print bigList as shown below:
for (int i = 0; i < bigList.size(); i++) {
System.out.println(bigList.get(i));
}
You can do the following:
bigList.stream()
.flatMap(Collection::stream)
.forEach(x -> System.out.println(x));
Output:
10
20
30
40
100
200
300
400
I have a table with products' names which locators differs only by index. I would like to use one method to iterate on all of the elements, because the number of elements can be changed up to 10 and I need to go through them all.
#FindBy(xpath="(//*[#class=\"product-name\"])[2]")
protected WebElement productName1;
#FindBy(xpath="(//*[#class=\"product-name\"])[3]")
protected WebElement productName2;
#FindBy(xpath="(//*[#class=\"product-name\"])[4]")
protected WebElement productName3;
A method that I want to parametrize is:
public String checkProductsInCart() {
wait.until(ExpectedConditions.visibilityOf(productName1));
String productName1String = productName1.getText();
return productName1String; }
How should I do that? I would appreciate your help.
Obtain all of the product name elements in a single list:
#FindBy(xpath="//*[#class=\"product-name\"]")
protected List<WebElement> productNameElements;
Then, in your test method, you can iterate over the elements (you could use for loop with an int index if you prefer):
List<String> productsInCart = new ArrayList<>();
for (WebElement element : productNameElements) {
productsInCart.add(nameOfProductInCart(element));
}
You can alter your check method to take a WebElement as a parameter:
public String nameOfProductInCart(WebElement element) {
wait.until(ExpectedConditions.visibilityOf(element));
return element.getText();
}
Alternatively, if this doesn't work (e.g. because the product list takes time to populate), you could use the WebDriver instance and programmatically perform each check:
List<String> productNames = new ArrayList<>();
for (int i = 2; i <= 10; i++) {
WebElement element = driver.findElement(By.xpath("(//*[#class=\"product-name\"])[" + i + "]"));
wait.until(ExpectedConditions.visibilityOf(element));
productNames.add(element.getText());
}
UPDATE: To answer the question in your comment, if you want the elements, rather than their text, you can store the elements themselves in a list:
List<WebElement> productNameElements = new ArrayList<>();
for (int i = 2; i <= 10; i++) {
WebElement element = driver.findElement(By.xpath("(//*[#class=\"product-name\"])[" + i + "]"));
wait.until(ExpectedConditions.visibilityOf(element));
productNameElements.add(element);
}
Now you can access the elements individually by getting them by index from the productNameElements list:
productNameElements.get(0); // First item
This should be easier to manage than having a separate variable for each item.
Just addendum to #ELEVATE's answer, You can find element via className:
#FindBy(className = "product-name")
private List<WebElement> tableItems;
or
#FindBy(xpath="//*[#class='product-name']")
private List<WebElement> tableItems;
but this depends if this is unique identifier...
Method :
public void itemAmountCollection() {
Map<String, List<Integer>> orderItemDetails = new LinkedHashMap<String, List<Integer>>();
ArrayList<Integer> itemsAmount = new ArrayList<Integer>();
WebElement orderItemTable = driver.findElement(By
.xpath("//*[#id='tblInfo']/tbody"));
List<WebElement> noOfItems = orderItemTable.findElements(By
.tagName("tr"));
for (int i = 1; i <= noOfItems.size(); i++) {
String itemAmount = driver.findElement(
By.xpath("//*[#id='tblInfo']/tbody/tr[" + i
+ "]/td[8]")).getText();
itemsAmount.add(Integer.parseInt(itemAmount));
orderItemDetails.put("amount", itemsAmount);
}
}
with above method we collected all the item amount with Map Collections and Output for the above method is (345,7905,345)
how can we add all the values in an particular Key (amount)
Expected Output :
8595 (i.e 345+7905+345)
I don't really get what you mean, but I'm amusing that you're trying to add all values in a List. To do this:
int result = 0;
for(int i : itemsAmount)
{
result+=1;
}
System.out.println(result);//This should print 8595.
In general Map<Key,List<Value>> structures end up needing code that looks as follows:
public addValue(Key key, Value value) {
if (!map.containsKey(key)) {
map.put(key, new ArrayList<>());
}
map.get(key).add(value);
}
In your case you should replace orderItemDetails.put with similar code.
Alternatively you could use a true Multimap from a third party library such as guava.
Summing the values would simply be:
map.get(key).stream().sum();
Assuming that the values are List which makes the stream an IntStream.
WebElement select = myD.findElement(By.xpath("//*[#id='custfoodtable']/tbody/tr[2]/td/div/select"));
List<WebElement> allOptions = select.findElements(By.tagName("option"));
for (WebElement option : allOptions) {
System.out.println(String.format("Value is: %s", option.getAttribute("value")));
option.click();
Object vaLue = "Gram";
if (option.getAttribute("value").equals(vaLue)) {
System.out.println("Pass");
} else {
System.out.println("fail");
}
}
I can verify one element in a list, but there are like 20 elements in a dropdown I need to verify and I do not want to use above logic 20 times. Is there any easier way to do it?
Don't use the for-each construct. It's only useful when iterating over a single Iterable / array. You need to iterate over the List<WebElement> and the array simultaneously.
// assert that the number of found <option> elements matches the expectations
assertEquals(exp.length, allOptions.size());
// assert that the value of every <option> element equals the expected value
for (int i = 0; i < exp.length; i++) {
assertEquals(exp[i], allOptions.get(i).getAttribute("value"));
}
EDIT after OP's changed his question a bit:
Assuming you have an array of expected values, you can do this:
String[] expected = {"GRAM", "OUNCE", "POUND", "MILLIMETER", "TSP", "TBSP", "FLUID_OUNCE"};
List<WebElement> allOptions = select.findElements(By.tagName("option"));
// make sure you found the right number of elements
if (expected.length != allOptions.size()) {
System.out.println("fail, wrong number of elements found");
}
// make sure that the value of every <option> element equals the expected value
for (int i = 0; i < expected.length; i++) {
String optionValue = allOptions.get(i).getAttribute("value");
if (optionValue.equals(expected[i])) {
System.out.println("passed on: " + optionValue);
} else {
System.out.println("failed on: " + optionValue);
}
}
This code essentially does what my first code did. The only real difference is that now you're doing the work manually and are printing the results out.
Before, I used the assertEquals() static method from the Assert class of the JUnit framework. This framework is a de-facto standard in writing Java tests and the assertEquals() method family is the standard way to verify the results of your program. They make sure the arguments passed into the method are equal and if they are not, they throw an AssertionError.
Anyway, you can do it the manual way, too, no problem.
You can do it like this:
String[] act = new String[allOptions.length];
int i = 0;
for (WebElement option : allOptions) {
act[i++] = option.getValue();
}
List<String> expected = Arrays.asList(exp);
List<String> actual = Arrays.asList(act);
Assert.assertNotNull(expected);
Assert.assertNotNull(actual);
Assert.assertTrue(expected.containsAll(actual));
Assert.assertTrue(expected.size() == actual.size());
public void verifyElementsInListEquals(List<WebElement> elementsList, String expectedValue) {
ArrayList<String> TextList =new ArrayList<>(); // new list to have Text from list of Webelement
for( WebElement x :elementsList){ //for each loop in JAVA
TextList.add(x.getText()); //add "x" times text to list above
}
if(TextList.contains(expectedValue)){ //check if value exist in list above
System.out.println("Value is there");
}
else{
System.out.println(" no value");
assertTrue(false); //will always stop the program here
}
}
I have a list like this
List contains set of dtime,uptime values.I want to get the list items i.e., dtime into one and
uptime into another variable.Likewise I want to get all the dtime and uptime pair values seperatly into
the variables using for loop in java.How can I achieve this.Is it possible list or vector?Please help me.
Pseudo code
List.get(0).get(0)-->gives 1st dtime
List.get(0).get(1)-->gives 1st uptime
List.get(1).get(0)-->gives 2nd dtime
List.get(1).get(1)-->gives 2nd uptime
And so on..
How to implement this with for loop I am not getting.I am new to java>please help me..
First Convert That ArrayList into Object[] array then get the value like given below code...driver_ModelsObj is an array convert that into drives object array then get the value from inside the array.
for(int indx=0;indx<driver_ModelsObj.size();indx++){
Object[] drivers=(Object[]) driver_ModelsObj.get(indx);
String Device_ID=drivers[0].toString();
}
If your list is as below
List list = [[1],[2],[3]];
We can retrieve the each value as below.
((List)list.get(0)).get(0); //This will retrieve value 1
((List)list.get(1)).get(0); //This will retrieve value 2
Sounds like you could use a domain object containing uptime and downtime.
For example,
public class Stats {
int dtime;
int uptime;
}
Then you can have a List<Stats> and access it like this:
mylist.get(0).dtime
mylist.get(0).uptime
mylist.get(1).dtime
mylist.get(1).uptime
Part of the (newer) Collcetions framework, List is almost always a better alternative than Vector
List.get(0).get(0)-->gives 1st dtime
List.get(0).get(1)-->gives 1st uptime
Well, what you're doing here, is getting the list at position 0, and getting item 1 from that list. In a for loop we can express this as:
for(int x = 0; x < List.size(); x++)
{
for(int y = 0; y < List.get(x).size(); y++)
{
if(y % 2 == 0)
{
// It's a dtime object.
}
else
{
// It's an uptime object.
}
}
}
Before this, you could declare some lists of your own:
List<DTime> listD = new ArrayList<ATimeObject>();
List<UpTime> listUp = new ArrayList<UpTime>();
Now when you're cycling through, all you need to do is add the relevant object:
if(y % 2 == 0)
{
listD.add(List.get(x).get(y));
}
else
{
listUp.add(List.get(x).get(y));
}
You should create a POJO like
public class TimeData {
double dtime;
Date uptime;
}
Then add each POJO to array list and then iterate it.
List<TimeData> oList = new ArrayList<TimeData>();
int nSize = oList.size();
for(int i=0;i<nSize;i++){
TimeData child = oList.get(i);
// get value using getters
}
You can try this ,Let say you have variables like
double dtime;
Timestamp tp;
And listofresults is coming from query results.
listofresults = results.getResultList();
If list is coming from query then put it in the loop this way in the condition of for loop
for(int i=0;i< listofresults.size() ;i=i+2)
{
dtime=(double) listofresults.get(i);
//cast because the value is of object type
tp=(TimeStamp) listofresults.get(i+1);
//cast because the value is of object type
//do something with these variables
}
I recommend creating a wrapper for it.
public class UpTimeDownTime {
MyTimeDataClass downtime;
MyTimeDataClass uptime;
public UpTimeDownTime(MyTimeDataClass downtime, MyTimeDataClass uptime){
this.downtime = downtime;
this.uptime = uptime;
}
public MyTimeDataClass getDowntime () {
return downtime;
}
public MyTimeDataClass getUptime () {
return uptime;
}
public static void main (String[] args) {
List<List<MyTimeDataClass>> List = ...;
List<UpTimeDownTime> uptimeDowntime = new ArrayList<UpTimeDownTime>();
for(List<MyTimeDataClass> timeList : List){
UpTimeDownTime u = new UpTimeDownTime(timeList.get(0), timeList.get(1));
uptimeDowntime.add(u);
}
}
}