Can someone please let me know what's the problem with the below code?
Am trying to sort an array stored in "Options" variable. But it throws 'Null' exception.
public static void CheckOptionsPresent(String s1) throws Exception
{
try
{
List optionsList=null;
webDriver.findElement(By.cssSelector("article.ContactInfo.active div.half-left.contactInfo div.idProvinceOfIssuance button")).click();
int listcount = webDriver.findElements(By.cssSelector("article.ContactInfo.active div.half-left.contactInfo div.idProvinceOfIssuance div ul li")).size();
System.out.println(listcount);
String[] options=new String[listcount];
for (int i=2; i<=listcount; i++ )
{
options[i-1] = webDriver.findElement(By.cssSelector("article.ContactInfo.active div.half-left.contactInfo div.idProvinceOfIssuance div ul li:nth-child("+i+") a span")).getText();
System.out.println(options[i-1]);
}
System.out.println(options.length);
for(int j=0; j<options.length;j++)
{
for (int i=j+1 ; i<options.length; i++)
{
if(options[i].compareToIgnoreCase(options[j])<0)
{
String temp= options[j];
options[j]= options[i];
options[i]=temp;
}
}
System.out.println(options[j]);
}
}
catch (RuntimeException e)
{
System.out.println(e.getMessage());
throw new RuntimeException(e.getMessage());
}
}
Output:
14
AB - Alberta
BC - British Columbia
MB - Manitoba
NB - New Brunswick
NL - Newfoundland and Labrador
NS - Nova Scotia
NT - Northwest Territories
NU - Nunavut
ON - Ontario
PE - Prince Edward Island
QC - Québec
SK - Saskatchewan
YT - Yukon Territory
14
Below is the error:
org.eclipse.debug.core.DebugException: com.sun.jdi.ClassNotLoadedException: Type has not been loaded occurred while retrieving component type of array.
for (int i=j+1 ; i<options.length; i++) {
if(options[i].compareToIgnoreCase(options[j])<0) {
String temp= options[j]; options[j]= options[i];
options[i]=temp;
}
}
String.compareToIgnoreCase() does not like null as its argument.
After your first loop, options[0] = null;
A NullPointerException happens when this gets hit on the first pass of if(options[i].compareToIgnoreCase(options[j])<0)then the indexes are (i = 1, j = 0).
Working Code :
public static void CheckOptionsPresent(String s1) throws Exception {
try {
List < String > optionsList = null;
webDriver.findElement(By.cssSelector("article.ContactInfo.active div.half-left.contactInfo div.idProvinceOfIssuance button")).click();
int listcount = webDriver.findElements(By.cssSelector("article.ContactInfo.active div.half-left.contactInfo div.idProvinceOfIssuance div ul li")).size();
System.out.println(listcount);
String[] options = new String[listcount];
for (int i = listcount; i >= 2; i--) {
options[i - 1] = webDriver.findElement(By.cssSelector("article.ContactInfo.active div.half-left.contactInfo div.idProvinceOfIssuance div ul li:nth-child(" + i + ") a span")).getText();
System.out.println(options[i - 1]);
optionsList = Arrays.asList(options);
}
System.out.println(optionsList);
System.out.println(isSorted(optionsList));
} catch (RuntimeException e) {
System.out.println(e.getMessage());
throw new RuntimeException(e.getMessage());
}
}
public static boolean isSorted(List < String > list) {
boolean sorted = true;
for (int i = 0; i < list.size() - 1; i++) {
if (list.get(i) == null) continue;
if (list.get(i).compareTo(list.get(i + 1)) > 0) sorted = false;
}
return sorted;
}
Related
I have an unsorted list with float values. I'm able to create graph from that.
But now, I want to create batches based on up and downs in that graph.
For example, I've an list like below
[6.17, 6.13, 6.12, 6.19, 6.2, 6.21, 6.28, 6.17, 6.2, 6.28]
First batch will be decreasing from 6.17 to 6.12 (index 0 to index 2).
Then second batch will be increasing from 6.12 to 6.28(index 3 to index 6)
All I can think of is to create two methods
increasing(List values) - to get all incremental values
decreasing(List values) - to get all decremental values
Call decreasing() method in increasing() method whenever I find sudden drop in values with sublist from last accessed element and vice-versa
But I don't think this is good idea.
Please find the graph image for reference
I've an object TimeAnalysis which contains start and end values.
In first case start=6.17 and end=6.12.
In second case start=6.12 and end=6.28
I want to get list of TimeAnalysis objects.
To actually split them up you can use Math.signum.
private List<List<Double>> splitAtInflectionPoints(List<Double> data) {
List<List<Double>> split = new LinkedList<>();
int start = 0;
for (int i = 1; i < data.size() - 1; i++) {
double leftSlope = Math.signum(data.get(i) - data.get(i - 1));
double rightSlope = Math.signum(data.get(i + 1) - data.get(i));
if (leftSlope != rightSlope) {
split.add(data.subList(start, i + 1));
start = i;
}
}
if (start < data.size()) {
split.add(data.subList(start, data.size()));
}
return split;
}
private void test() {
List<Double> data = Arrays.asList(6.17, 6.13, 6.12, 6.19, 6.2, 6.21, 6.28, 6.17, 6.2, 6.28);
for (List<Double> run : splitAtInflectionPoints(data)) {
System.out.println(run);
}
}
Prints:
[6.17, 6.13, 6.12]
[6.12, 6.19, 6.2, 6.21, 6.28]
[6.28, 6.17]
[6.17, 6.2, 6.28]
You can create a class that stores the list of values and type of Batch.
class Batch {
enum BatchType {
INCREASING,
DECREASING
};
BatchType batchType;
List<Float> values;
}
Now you can have a method called splitIntoBatches which returns a list of Batch.
public List<Batch> splitIntoBatches(List<Float> values) {
// Traverse through the list once and create list of batches.
}
You can loop through elements in your array and track if it's increasing or decreasing or possibly the same.
I used TimeAnalysis class you mentioned and wrote a static method splitList().
It is to split the list of time floats into list of TimeAnalysis.
public static List<TimeAnalysis> splitList(List<Float> timeList) {
if(timeList.size() == 0) return new ArrayList<>();
else if(timeList.size() == 1) {
List<TimeAnalysis> batches = new ArrayList<>();
batches.add(new TimeAnalysis(timeList.get(0), timeList.get(0)));
return batches;
}
ArrayList<TimeAnalysis> batches = new ArrayList<>();
// 0: same, 1: inc, 2: dec
int type = -1;
TimeAnalysis lastBatch = new TimeAnalysis(timeList.get(0), timeList.get
batches.add(lastBatch);
timeList.remove(0);
for(float t : timeList) {
switch(type) {
case 0: // same
if(t > lastBatch.end) { // inc
lastBatch = new TimeAnalysis(lastBatch.end, t);
batches.add(lastBatch);
type = 1;
} else if(t < lastBatch.end) { // dec
lastBatch = new TimeAnalysis(lastBatch.end, t);
batches.add(lastBatch);
type = 2;
}
break;
case 1: // inc
if(t > lastBatch.end) { // inc
lastBatch.end = t;
} else if(t < lastBatch.end) { // dec
lastBatch = new TimeAnalysis(lastBatch.end, t);
batches.add(lastBatch);
type = 2;
} else { // same
lastBatch = new TimeAnalysis(lastBatch.end, t);
batches.add(lastBatch);
type = 0;
}
break;
case 2: // dec
if(t > lastBatch.end) { // inc
lastBatch = new TimeAnalysis(lastBatch.end, t);
batches.add(lastBatch);
type = 1;
} else if(t < lastBatch.end) {
lastBatch.end = t;
} else {
lastBatch = new TimeAnalysis(lastBatch.end, t);
batches.add(lastBatch);
type = 0;
}
break;
default:
if(t > lastBatch.end) type = 1;
else if(t < lastBatch.end) type = 2;
else type = 0;
lastBatch.end = t;
break;
}
}
return batches;
}
When I run:
Scanner in = new Scanner(System.in);
ArrayList<Float> input = new ArrayList<>();
for(int i=0; i<10; i++) input.add(in.nextFloat());
List<TimeAnalysis> output = TimeAnalysis.splitList(input);
for(TimeAnalysis batch : output) System.out.println("start: " + batch.start + ", end: " + batch.end);
and give your data as input, I get:
start: 6.17, end: 6.12
start: 6.12, end: 6.28
start: 6.28, end: 6.17
start: 6.17, end: 6.28
I have 2 array...1 with the name of the person who pay something and another one with the price of each payment. If a person didn't buy anything, the arrayPrice with the same index of the nameArray at the "name" position, is empty. How can I set a default value to "0" --> big decimal , if the entry is null?
That's my code that fill the array with only [0], even if I have 1 person with 1 payment:
db.collection("users").document(email).collection("Group").document(groupName)
.get()
.addOnCompleteListener(new OnCompleteListener<DocumentSnapshot>() {
#Override
public void onComplete(#NonNull Task<DocumentSnapshot> task) {
if (task.isSuccessful()) {
DocumentSnapshot document = task.getResult();
// Getting all the partecipants of a group
String[] values = (String.valueOf(document.get("partecipant")).replace("[", "").replace("]", "").replace(" ", "").split(","));
for(String value : values){
nameArray.add(value);
}
Log.v("nameArraydownloaded", nameArray.toString());
}
}
});
DocumentReference docRef = db.collection("users").document(email).collection("Group").document(groupName);
docRef.collection("Payments")
.get()
.addOnSuccessListener(new OnSuccessListener<QuerySnapshot>() {
#Override
public void onSuccess(QuerySnapshot queryDocumentSnapshots) {
for (QueryDocumentSnapshot document : queryDocumentSnapshots) {
//Extracting payment description from each document
cont += 1;
//Extracting cost and who payed from each document
price = document.getString("cost");
priceFloat += Float.parseFloat(price);
priceArray.add(new BigDecimal(price));
name = document.getString("paid by");
nameArray.add(name);
}
numberOfPaymentTV.setText(String.valueOf(cont));
totalCost.setText(decimalFormat.format(priceFloat) + "€");
cpp = decimalFormat.format(priceFloat / Float.parseFloat(num_partecipants));
costPerPerson.setText(cpp + "€");
while(priceArray.size() < nameArray.size()){
priceArray.add(BigDecimal.valueOf(0));
}
if (nameArray.size() > 0) {
// Manipulate the arrays
Map<String, BigDecimal> totals = new HashMap<>();
for (int i = 0; i < nameArray.size(); ++i) {
String name = nameArray.get(i);
BigDecimal price = priceArray.get(i);
BigDecimal total = totals.get(name);
if (total != null) {
totals.put(name, total.add(price));
} else {
totals.put(name, price);
}
}
nameArray.clear();
priceArray.clear();
// Adding single name and price value for each partecipant
for (Map.Entry<String, BigDecimal> entry : totals.entrySet()) {
nameArray.add(entry.getKey());
priceArray.add(entry.getValue());
}
// Order the array by descending price
for (int i = 0; i < priceArray.size(); i++) {
for (int j = 0; j < priceArray.size() - 1; j++) {
if (priceArray.get(j).compareTo(priceArray.get(j + 1)) < 0) {
BigDecimal tempPrice = priceArray.get(j);
String tempName = nameArray.get(j);
priceArray.set(j, priceArray.get(j + 1));
nameArray.set(j, nameArray.get(j + 1));
priceArray.set(j + 1, tempPrice);
nameArray.set(j + 1, tempName);
}
}
}
Log.v("priceArray", priceArray.toString());
for (int i = 0; i < nameArray.size() - 1; i++) {
if (BigDecimal.valueOf(Float.parseFloat(cpp.replace(",", "."))).subtract(priceArray.get(i)).compareTo(BigDecimal.ZERO) < 0) {
receiverArray.add(nameArray.get(i));
}
}
for (int i = 1; i < nameArray.size(); i++) {
if (BigDecimal.valueOf(Float.parseFloat(cpp.replace(",", "."))).subtract(priceArray.get(i)).compareTo(BigDecimal.ZERO) > 0) {
debtorArray.add(nameArray.get(i));
}
}
if (receiverArray.size() > debtorArray.size()) {
for (int i = 0; i < nameArray.size() - 1; i++) {
differenceArray.add(priceArray.get(i).subtract(BigDecimal.valueOf(Float.parseFloat(cpp.replace(",", ".")))).abs());
}
} else {
for (int i = 1; i < nameArray.size(); i++) {
differenceArray.add(priceArray.get(i).subtract(BigDecimal.valueOf(Float.parseFloat(cpp.replace(",", ".")))).abs());
}
}
if (!receiverArray.isEmpty() && !debtorArray.isEmpty()) {
while (receiverArray.size() < debtorArray.size()) {
receiverArray.add(receiverArray.get(receiverArray.size() - 1));
}
while (debtorArray.size() < receiverArray.size()) {
debtorArray.add(debtorArray.get(debtorArray.size() - 1));
}
}
Log.v("recArray", receiverArray.toString());
Log.v("debArray", debtorArray.toString());
Log.v("difArray", differenceArray.toString());
customAdapter = new ReportAdapter(getActivity(), debtorArray, receiverArray, differenceArray);
listView.setAdapter(customAdapter);
}
}
The array with this code is [14.00], but there are 3 person in the name array, and I need the priceArray to be: [14.00, 0, 0]
How can I do that?
You need map.getOrDefault("key", <defaultValue>) .
Returns the value to which the specified key is mapped, or
defaultValue if this map contains no mapping for the key.
i need help. can somebody tell me about concept and example code i need use? the case is, I want input game history using java into mysql (phpmyadmin).
I'm already create like this if S0: 1.0; and all value zero
try
{
connection = dbManager.getConnection();
String bs = "S0:"+s[0]+"; S1:"+s[1]+"; S2:"+s[2]+"; S3:"+s[3]+"; S4:"+s[4]+"; S5:"+s[5]+"; S6:"+s[6]+"; S7:"+s[7]+"; S8:"+s[8]+"; S9:"+s[9]+"; S10:"+s[10]+"; S11:"+s[11]+"; S12:"+s[12]+"; S13:"+s[13]+"; S14:"+s[14]+"; S15:"+s[15]+"; S16:"+s[16]+"; S17:"+s[17]+"; S18:"+s[18]+"; S19:"+s[19]+"; S20:"+s[20]+"; S21:"+s[21]+"; S22:"+s[22]+"; S23:"+s[23]+"; S24:"+s[24]+"; S25:"+s[25]+"; S26:"+s[26]+"; S27:"+s[27]+"; S28:"+s[28]+"; S29:"+s[29]+"; S30:"+s[30]+"; S31:"+s[31]+"; S32:"+s[32]+"; S33:"+s[33]+"; S34:"+s[34]+"; S35:"+s[35]+"; S36:"+s[36]+"";
}
catch (SQLException e)
{
trace("player 1 update error");
}
and it's working and result like this
S0:1.0; S1:0.0; S2:0.0; S3:0.0; S4:0.0; S5:0.0; S6:0.0; S7:0.0; S8:0.0; S9:0.0; S10:0.0; S11:0.0; S12:0.0; S13:0.0; S14:0.0; S15:0.0; S16:0.0; S17:0.0; S18:0.0; S19:0.0; S20:0.0; S21:0.0; S22:0.0; S23:0.0; S24:0.0; S25:0.0; S26:0.0; S27:0.0; S28:0.0; S29:0.0; S30:0.0; S31:0.0; S32:0.0; S33:0.0; S34:0.0; S35:0.0; S36:0.0
but it's not efficient, the question is how i can input if there have any value except zero, example like S0:1 ; S1:0 ; S2:1 and insert into mysql just like this S0:1 ; S2:1 so if there no have value / zero, not being inserted. Thanks
You could try this:
String bs = "";
int count = 0;
for (int i = 0; i < size; i++) {
if(!s[i].equals(0.0)) {
if(count > 0) {
bs += " ; " ;
}
bs += "S" + count + ":" + s[i].split(".")[0];
count++;
}
}
try this code
private static String format (int x) {
if (x == 0) {
return null;
}
return String.format ("S%d = %d; ", x ,x);
}
// testing from main
{
StringBuilder buf = new StringBuilder();
for (int x = 0; x < 4; x++) { // dummy input stream
String rv = format (x);
if (rv != null) {
buf.append(rv);
}
}
System.out.println(buf.toString());
}
I'm trying to build simple multithreading application. But I'm confused about Java monitors. I have many threads that want to format with their data one array. So for example I have Supermarket Threads (data of the thread is in txt file) So first thread have these product (Milk, Cheese, Chocolate) and country code for each product 1,2, 3
SupermarketA
Milk 1
Cheese 2
Chocolate 3
SupermarketB
Yogurt 1
Orangle 2
Bannana 3
Tea 7
Kiwi 9
and I want to format array that has to fields (country_code and count)
So my array should look like that
Country_code count
1 2
2 2
3 2
7 1
9 1
Code
public class SortedArray{
private int num = 0; // num is country code
private int count = 0;
}
So here's my monitor class
public class SingleArray {
private SortedArray[] array;
private int arrayIndex;
private static final int MAX_SIZE = 5;
public SingleArray() {
array = new SortedArray[MAX_SIZE];
arrayIndex = 0;
initArray();
}
private void initArray() {
for (int i = 0; i < MAX_SIZE; i++) {
array[i] = new SortedArray();
}
}
public synchronized void inc(){
awaitUnderMax();
notifyAll();
}
private void awaitUnderMin(){
while (arrayIndex == 0) try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public synchronized void dec(){
awaitUnderMin();
notifyAll();
}
public void add(ArrayList<Integer> count){
for (int i = 0; i < count.size(); i++) {
singleArray.inc();
int num = count.get(i);
if (singleArray.arrayIndex == 0) { // if array is empty add value to it
singleArray.array[0].num = num;
singleArray.array[0].count++;
singleArray.arrayIndex++;
} else {
if (!isThere(num)) { // if num is a new value to array
singleArray.inc();
int index1 = singleArray.arrayIndex;
if (num > singleArray.array[index1 - 1].num) {
singleArray.inc();
singleArray.array[index1].num = num;
singleArray.inc();
singleArray.array[index1].count++;
singleArray.inc();
singleArray.arrayIndex++;
System.out.println(Thread.currentThread().getName() + " first " + singleArray.array[index1].num);
} else if (num < singleArray.array[index1 - 1].num) { // jei num mazesne uz paskutinia masyvo reiksme
int index = index1 - 1 < 0 ? index1 : index1 - 1;
while (index > 0 && num < singleArray.array[index].num) {
index--;
}
if (index != singleArray.arrayIndex) {
System.out.println(Thread.currentThread().getName() + " sec " + singleArray.array[index].num);
singleArray.array = addPos(singleArray.array, index + 1, num);
}
}
}
}
}
}
public boolean isThere(int number){
for(int i=0; i<singleArray.arrayIndex; i++){
singleArray.inc();
if(number == singleArray.array[i].num){
singleArray.array[i].count++;
return true;
}
}
return false;
}
private void awaitUnderMax(){
while (arrayIndex >= MAX_SIZE) try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public synchronized void removeValue(int number, int howManyItems){
for(int i=0; i<arrayIndex; i++){
dec();
if(number == array[i].num){
int numberToDelete = array[i].count - howManyItems >= 0 ? howManyItems : array[i].count;
if(array[i].count >= numberToDelete){
array[i].count -= numberToDelete;
}
if(array[i].count == 0){
deleteItem(i);
}
}
if(array[i].count == 0){
deleteItem(i);
}
}
}
Each thread call add(ArrayList<Integer> count) method
So basically what add method does:
Find place where to insert new value (dependng if new value is greater or lower than a previous)
call isThere(int num) method that check if new value is already in array (if so increment count singleArray.array[i].count++) otherwise add new value to array
If array is full arrayIndex == MAX_SIZE wait current thread for other threads to decrement arrayIndex (this is oly one part of code I also have other threads that based on county code decrement array)
So the biggest problem is that multiplethreads need to update single array at the same time (I know that adding synchronized keyword to add method should solve this problem but it only let one thread to run this method at once!) So sometimes all works fine, but sometimes I get really starnge results (for example that country code is 0 (That is imposible!!!) and sometimes new values is placed in wrong array posiitons). Also I think that semaphores should solve this problem, but is it possible to do that with monitors? Thank's for the answers.
EDIT v2
to #Elyasin
public Thread[] setUpShopsBuilderThreads(){
int size = data.getSize();
ArrayList<ArrayList<String>> a = new ArrayList<>();
ArrayList<ArrayList<Integer>> b = new ArrayList<>();
ArrayList<ArrayList<Double>> c = new ArrayList<>();
Thread[] threads = new Thread[size];
for (int i = 0; i < size; i++) {
int tmp = data.getIndex(i);
int range = i + 1 < size ? data.getIndex(i + 1) : data.getWaresSize();
ArrayList<String> name = new ArrayList<>();
ArrayList<Integer> count = new ArrayList<>();
ArrayList<Double> price = new ArrayList<>();
for (int j = tmp; j < range; j++) {
name.add(data.getName(j));
count.add(data.getCount(j));
price.add(data.getPrice(j));
}
a.add(name);
b.add(count);
c.add(price);
}
procesas_1 p1 = new procesas_1(a.get(0), b.get(0), c.get(0));
procesas_2 p2 = new procesas_2(a.get(1), b.get(1), c.get(1));
procesas_3 p3 = new procesas_3(a.get(2), b.get(2), c.get(2));
procesas_4 p4 = new procesas_4(a.get(3), b.get(3), c.get(3));
procesas_5 p5 = new procesas_5(a.get(4), b.get(4), c.get(4));
Thread worker1 = new Thread(p1);
Thread worker2 = new Thread(p2);
Thread worker3 = new Thread(p3);
Thread worker4 = new Thread(p4);
Thread worker5 = new Thread(p5);
threads[0] = worker1;
threads[1] = worker2;
threads[2] = worker3;
threads[3] = worker4;
threads[4] = worker5;
return threads;
}
public static void main(String[] args) {
Starter start = new Starter();
start.read();
start.printShopsData();
start.printUserData();
Thread[] builderThreads = start.setUpShopsBuilderThreads();
for(int i=0; i<builderThreads.length; i++){
builderThreads[i].start();
}
}
what about using the concurrent safe datasets java already provides?
if you want it sorted, this one looks it might work for you:
http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ConcurrentSkipListSet.html
just add it as in a normal Collection
ok here's the block of code i wrote :
public ArrayList<Location> possibleMoves() {
ArrayList<Location> a1 = new ArrayList<Location>(); // an array to contain all possible locations
Board testB = new Board(); // a test board to test if locations are valid or not
// locations have x & y coordinates
a1.add(new Location(getCurrentLocation().getx() - 1, getCurrentLocation().gety() + 1));
a1.add(new Location(getCurrentLocation().getx() + 1, getCurrentLocation().gety() - 1));
a1.add(new Location(getCurrentLocation().getx() - 1, getCurrentLocation().gety() - 1));
a1.add(new Location(getCurrentLocation().getx() + 1, getCurrentLocation().gety() + 1));
for (int i = 0; i < a1.size(); i++) {
try {
Tower testTower = testB.getGrid()[a1.get(i).getx()][a1.get(i).gety()];
}catch(ArrayIndexOutOfBoundsException e) {
a1.remove(a1.get(i));
}
}
return a1;
}
When you remove the element, the position of the following ones is decreased. Do this also to i. And, you can just use remove(int).
for (int i = 0; i < a1.size(); i++) {
try {
Tower testTower = testB.getGrid()[a1.get(i).getx()][a1.get(i).gety()];
} catch(ArrayIndexOutOfBoundsException e) {
a1.remove(i--);
}
}
If you want to remove elements from a List while visiting its elements I suggest to used the following pattern:
Iterator<Location> locationsIt = a1.iterator();
while (locationsIt.hasNext()) {
Location location = locationsIt.next();
try {
Tower testTower = testB.getGrid()[location.getx()][location.gety()];
} catch(ArrayIndexOutOfBoundsException e) {
locationsIt.remove();
}
}
It's easy to use and it's not error prone.