I am using MpAndroidChart library and trying to set custom labels using this method:
String[] daysOfTheWeek = {"M","T","W","T","F","S","S"};
XAxis xAxis = barChart.getXAxis();
xAxis.setValueFormatter(new ValueFormatter() { //Returns a string not a list :(
#Override
public String getFormattedValue(float value) {
int position = 0;
for(int i =0; i<daysOfTheWeek.length;i++){
position = i;
}
return daysOfTheWeek[position];
}
});
However I only get the last item of the array = S.
How can I return all the items individually?
use this
String[] daysOfTheWeek = {"M","T","W","T","F","S","S"};
XAxis xAxis = barChart.getXAxis();
int position = 0;
for(int i =0; i<daysOfTheWeek.length;i++){
position = i;
xAxis.setValueFormatter(new ValueFormatter() { //Returns a string not a list :(
#Override
public String getFormattedValue(float value) {
return daysOfTheWeek[position];
}
}
})
If you want to return the last item of array use this:
return daysOfTheWeek[daysOfTheWeek.length-1];
If you want to get items individually, you could create a method that gets position of item and return that item:
public String getItem(int position)
{
return daysOfTheWeek[position];
}
Silly me, the method accepts a float value. I simply had to use it!
xAxis.setValueFormatter(new ValueFormatter() {
#Override
public String getFormattedValue(float value) {
return daysOfTheWeek[(int)value];
}
});
Try it..
XAxis xAxis = lineChart.getXAxis();
xAxis.setPosition(XAxis.XAxisPosition.BOTTOM);
xAxis.setDrawGridLines(false);
xAxis.setValueFormatter(new IndexAxisValueFormatter(getAreaCount));
public ArrayList<String> getAreaCount() {
ArrayList<String> label = new ArrayList<>();
for (int i = 0; i < areaList.size(); i++)
label.add(areaList.get(i).getTopicName());
return label;
}
This trick works 100% for me to display week days from Mo to SU
chartWeeklyDistance.getXAxis().setAxisMinimum(0);
String[] daysOfTheWeek = {"MO", "TU", "WE", "TH", "FR", "SA", "SU"};
xAxis.setValueFormatter(new ValueFormatter() {
#Override
public String getFormattedValue(float value) {
if (((int) value) > -1 && ((int) value) < 7) {
return daysOfTheWeek[((int) value)];
}
return "";
}
});
Related
public enum Operator {
PLUS("+"),
MINUS("-");
private final String operator;
Operator(String operator) {
this.operator = operator;
}
public String getOperator() {
return operator;
}
public static Operator getByValue(String operator) {
for (Operator operatorEnum : Operator.values()) {
if (operatorEnum.getOperator().equals(operator)) {
return operatorEnum;
}
}
throw new IllegalArgumentException("Invalid value");
}
}
//////////
public enum MetricConvertor {
m(1000),
cm(10),
mm(1),
km(1000000),
dm(100);
private int scale;
MetricConvertor(int scale) {
this.scale = scale;
}
public int getScale() {
return scale;
}
}
/////////
public class Application {
public static void main(String[] args) {
int scale = MetricConvertor.valueOf("m").getScale();
}
I wan to create a calculator that is capable of computing a metric distance value from an expression that contains different scales and systems.
Output should be specified by the user.
Only Addition and subtraction is allowed.
Output is in lowest unit.
Expression: 10 cm + 1 m - 10 mm
Result: 1090 mm
I am stuck at this point, how can I add or substract the values for a list and convert them at the lowest scale sistem( eg above mm, but it can be dm if are added for example dm + m + km)
Here is solution
split each string by add/minus and add it to appropriate list
split number and metric in each list(can use matcher) and sum it
result = sumAdd - sumMinus(mm).
Please optimize it, because i don't have time to optimize this code, I need to go to bed :D
Result is in mm, so you have to get lowest metric and recaculate it(leave it to you).
private static int caculator(String exp) {
List<String> addList = new ArrayList<>();
List<String> minusList = new ArrayList<>();
int checkPoint = 0;
boolean op = true;//default first value is plus
// Split string with add/minus
for (int i = 1; i < exp.length(); i++) {
String s = exp.substring(i, i + 1);
if (Operator.PLUS.getOperator().equals(s)) {
checkOperator(addList, minusList, op, exp.substring(checkPoint, i).trim());
checkPoint = i + 1;
op = true;
continue;
}
if (Operator.MINUS.getOperator().equals(s)) {
checkOperator(addList, minusList, op, exp.substring(checkPoint, i).trim());
checkPoint = i + 1;
op = false;
continue;
}
}
// Add last string
checkOperator(addList, minusList, op, exp.substring(checkPoint).trim());
// Get sum each list
int sumAdd = sumList(addList);
int sumMinus = sumList(minusList);
return sumAdd - sumMinus;
}
//sum a list
private static int sumList(List<String> addList) {
int sum = 0;
for (String s: addList) {
String[] arr = s.split(" ");
int value = Integer.parseInt(arr[0]);
int scale = MetricConvertor.valueOf(arr[1]).getScale();
sum += value * scale;
}
return sum;
}
// check operator to put into approriate list
private static void checkOperator(List<String> addList, List<String> minusList, boolean op, String substring) {
if (op) {
addList.add(substring);
} else {
minusList.add(substring);
}
}
I have a text file containing the following strings (which are versions of a software):
1_10_2_0_154
3_10_5_2_10
2_10_4_1
3_10_5_1_37
I'm trying to find the most recent version, in this case 3_10_5_2_10 is the version that I'm trying to display using java.
For the moment, here is my code:
BufferedReader br;
String version;
ArrayList<List<Integer>> array = new ArrayList<List<Integer>>();
List<Integer> liste = new ArrayList<Integer>();
try{
br = new BufferedReader(new FileReader(new File(FILEPATH)));
while((version= br.readLine()) != null)
{
liste = Arrays.asList(version.split("_")).stream().
map(s -> Integer.parseInt(s.trim())).collect(Collectors.toList());
array.add(liste);
}
for(int i = 0; i < array.size(); i++)
{
for (List l: array)
{
Object z = l.get(i);
List<Object> listes = new ArrayList<Object>();
listes.add(z);
System.out.println(listes);
}
}
br.close();
System.out.println(array);
}catch(FileNotFoundException e){
e.printStackTrace();
}catch(IOException e){
e.printStackTrace();
}
I made a loop to save strings to ArrayList> like:
[[1,10,2,0,154] , [3,10,5,2,10], [2,10,4,1], [3,10,5,1,37]]
I want to get the elements of each list and compare them to find the most biggest one (most recent one) but I don't know to do that..
I sugguest you a object approach, define a class named Version with compareTo method, then using method sort on Collections class you can simply sort your versions.
Advantages
Clean and Clear code
Data validation
Main:
public class Main {
public static void main(String[] args){
List<Version> versions = Arrays.asList(
Version.create("1_10_2_0_154"),
Version.create("3_10_5_2_10"),
Version.create("2_10_4_1_49"),
Version.create("3_10_5_1_37"));
versions.sort(Version::compareTo);
System.out.println(versions.get(0).toString());
}
}
Version:
public class Version implements Comparable<Version> {
private final int major;
private final int minor;
private final int bug;
private final int release;
private final int build;
public Version(int major, int minor, int bug, int release, int build) {
this.major = major;
this.minor = minor;
this.bug = bug;
this.release = release;
this.build = build;
}
public int getMajor() {
return major;
}
public int getMinor() {
return minor;
}
public int getBug() {
return bug;
}
public int getRelease() {
return release;
}
public int getBuild() {
return build;
}
#Override
public String toString() {
return "Version{" +
"major=" + major +
", minor=" + minor +
", bug=" + bug +
", release=" + release +
", build=" + build +
'}';
}
public static Version create(String value){
String[] splitRes = value.split("_");
List<Integer> intValues = new ArrayList<>();
for(String v : splitRes){
intValues.add(Integer.parseInt(v));
}
return create(intValues);
}
public static Version create(List<Integer> values){
if(Objects.requireNonNull(values).size() < 5)
throw new IllegalArgumentException();
return new Version(
values.get(0),
values.get(1),
values.get(2),
values.get(3),
values.get(4)
);
}
#Override
public int compareTo(Version that) {
if (this.major > that.major) {
return -1;
} else if (this.major < that.major) {
return 1;
}
if (this.minor > that.minor) {
return -1;
} else if (this.minor < that.minor) {
return 1;
}
if (this.bug > that.bug) {
return -1;
} else if (this.bug < that.bug) {
return 1;
}
if (this.release > that.release) {
return -1;
} else if (this.release < that.release) {
return 1;
}
if (this.build > that.build) {
return -1;
} else if (this.build < that.build) {
return 1;
}
return 0;
}
}
UPDATE 1
As suggested by #Henrik i updated the list sorting with a Java 8 approach.
UPDATE 2
I reversed the compareTo method so now you can simply do plain sort calling sort method on list and passing method reference Version::compareTo
UPDATE 3
A more dynamic solution for Version class:
public class Version implements Comparable<Version> {
private final List<Integer> values;
public Version(List<Integer> values) {
this.values = values;
}
public List<Integer> getValues() {
return values;
}
#Override
public String toString() {
return String.join("_", values
.stream()
.map(Object::toString)
.collect(Collectors.toList()));
}
#Override
public int compareTo(Version that) {
List<Integer> thatValues = that.getValues();
for(int index = 0; index < values.size(); index++){
Integer value = values.get(index);
Integer thatValue = thatValues.get(index);
if (value > thatValue) {
return -1;
} else if (value < thatValue) {
return 1;
}
}
return 0;
}
public static Version create(String value){
String[] splitRes = value.split("_");
List<Integer> intValues = new ArrayList<>();
for(String v : splitRes){
intValues.add(Integer.parseInt(v));
}
return new Version(intValues);
}
}
You can write a Comparator to compare two Lists
Comparator<List<Integer>> comparator = (list1, list2) -> {
Iterator<Integer> iteratorA = list1.iterator();
Iterator<Integer> iteratorB = list2.iterator();
//It iterates through each list looking for an int that is not equal to determine which one precedes the other
while (iteratorA.hasNext() && iteratorB.hasNext()) {
int elementA = iteratorA.next();
int elementB = iteratorB.next();
if (elementA > elementB) {
return 1;
} else if (elementA < elementB) {
return -1;
}
}
//All elements seen so far are equal. Use the list size to decide
return iteratorA.hasNext() ? 1 : iteratorB.hasNext() ? -1 : 0;
};
You can sort it as
Collections.sort(list, comparator);
EDIT: You can refer to David Geirola's answer to convert the version string as a POJO and move the comparator logic inside that. But that is highly tied/coupled to the input string format. My solution works for any List<List<Integer>>.
A simple object oriented approach would be to create object, representing version number, let's call it VersionNumber, which would have a constructor of a factory method that does the parsing of the string. This VersionNumber class should implement interface Comparable and implement method compareTo.
Here is a hint for using Comparable Why should a Java class implement comparable?
Then you can easily write an algorithm to find the max version or google some library that would do it for you.
It is not optimized but should work. You can use both of comparators.
static List<String> versions = Arrays.asList(
"1_10_2_0_154",
"3_10_5_2_10",
"2_10_4_1_49",
"3_10_5_1_37");
static Comparator<List<Integer>> c = (o1,o2) -> {
int length = o1.size()>o2.size()?o2.size():o1.size();
for (int i = 0; i < length; i++) {
int i1 = o1.get(i);
int i2 = o2.get(i);
if (i1 != i2)
return i1 - i2;
}
return 0;
};
static Comparator<List<Integer>> c2 = (o1,o2) -> {
Iterator<Integer> i1=o1.iterator();
Iterator<Integer> i2=o2.iterator();
while (i1.hasNext() && i2.hasNext()){
int i = i1.next()-i2.next();
if (i!=0) return i;
}
return 0;
};
static Optional<List<Integer>> getTheMostRecentVersion(List<String> versions) {
return versions.stream().
map(s -> Arrays.stream(s.split("_")).
map(Integer::parseInt).
collect(Collectors.toList())).max(c2);
}
I think that this text file could be very big and it is better to compare each line on the fly (instead of store all line into collection to sort it after):
public static String getMostRecentVersion(BufferedReader in) throws IOException {
final Comparator<String[]> version = (s1, s2) -> {
int res = 0;
for (int i = 0; i < 5 && res == 0; i++)
res = Integer.compare(Integer.parseInt(s1[i]), Integer.parseInt(s2[i]));
return res;
};
String str;
String resStr = null;
String[] resPparts = null;
while ((str = in.readLine()) != null) {
String[] parts = str.split("_");
if (resStr == null || version.compare(parts, resPparts) > 0) {
resStr = str;
resPparts = parts;
}
}
return resStr;
}
A general ListComparator should help.
static class ListComparator<T extends Comparable<T>> implements Comparator<List<T>> {
#Override
public int compare(List<T> o1, List<T> o2) {
for (int i = 0; i < Math.max(o1.size(), o2.size()); i++) {
int diff =
// Off the end of both - same.
i >= o1.size() && i >= o2.size() ? 0
// Off the end of 1 - the other is greater.
: i >= o1.size() ? -1
: i >= o2.size() ? 1
// Normal diff.
: o1.get(i).compareTo(o2.get(i));
if (diff != 0) {
return diff;
}
}
return 0;
}
}
private static final Comparator<List<Integer>> BY_VERSION = new ListComparator<Integer>().reversed();
public void test(String[] args) {
String[] tests = {
"1_10_2_0_154",
"3_10_5_2_10",
"2_10_4_1_49",
"3_10_5_1_37",
"3_10_5_1_37_0"
};
System.out.println("Before: " + Arrays.toString(tests));
System.out.println("After: " + Arrays.stream(tests)
// Split into parts.
.map(s -> s.split("_"))
// Map String[] to List<Integer>
.map(a -> Arrays.stream(a).map(s -> Integer.valueOf(s)).collect(Collectors.toList()))
// Sort it.
.sorted(BY_VERSION)
// Back to a new list.
.collect(Collectors.toList()));
}
slap your arrays together into a number then just do number comparison.
class Scratch
{
public static void main(String[] args)
{
List<List<Integer>> arr = new ArrayList<>();
arr.add(fromArray(new Integer[]{1,10,2,0,154}));
arr.add(fromArray(new Integer[]{3,10,5,2,10}));
arr.add(fromArray(new Integer[]{2,10,4,1,49}));
arr.add(fromArray(new Integer[]{3,10,5,1,37}));
Integer[] maxLengths = {0,0,0,0,0};
for (List<Integer> v : arr)
{
for(int idx = 0; idx < v.size(); idx++)
{
Integer n = v.get(idx);
int curMaxLen = maxLengths[idx];
maxLengths[idx] = Math.max(n.toString().length(), curMaxLen);
}
}
Long largest = arr.stream().map(v -> {
StringBuilder result = new StringBuilder();
for(int idx = 0; idx < v.size(); idx++)
{
Integer n = v.get(idx);
int maxLen = maxLengths[idx];
result.append(String.format("%-" + maxLen + 's', n).replace(' ', '0'));
}
return result.toString();
}).map(Long::valueOf).max(Comparator.naturalOrder()).get();
System.out.println(largest);
}
public static List<Integer> fromArray(Integer[] array)
{
List<Integer> list = new ArrayList<>();
Collections.addAll(list, array);
return list;
}
}
Below is my model:
public class Products {
String date = "", item = "";
public Products () {
}
public Products (String date String item ) {
this.date = date
this.item = item ;
}
public String getdate() {
return date
}
public void setdate (String date) {
this.date = date
}
public String getitem () {
return item
}
public void setitem (String item) {
this.item = item
}
}
And below code for defined the Arralist:
private ArrayList<TasksCharts> mArrayList;
and i have data in ArrayList:
position 0 -> date - "2016-10-02" , item = "pens"
position 1 -> date - "2016-10-03" , item = "xyz"
position 2 -> date - "2016-10-03" , item = "fts"
Now i want the position of ArraList whose contain "pens" . So for that i have eritten below code:
if (containsSubString(mArrayList, "pens")) {
int listIndex = getItemPos("pens");
}
private int getItemPos(String item) {
return mArrayList.indexOf(item);
}
When i runt this it will give me -1 index for item pens.
How can i get the index of particular item ?
Does a TasksCharts Object containing pens equal a String Object containing pens?
Unless you have overriden the equals method I would say "no".
I would recommend that you use a Map instead or you will have to loop through looking for a TasksCharts Object containing pens
You can run a for loop to get job done .
private int getItempos(ArrayList<TasksCharts> mArrayList, String str)
{
for(int i=0;i<mArrayList.size();i++)
{
if(mArrayList.get(i).item.indexOf(str)!=-1)
{
return i;
}
}
return -1;
}
Hope this helps!
you should do sth like this :
private int getItemPos(String key , String item) {
int i = 0;
for (i=0; i<mArrayList.size(); i++)
{
if(mArrayList.get(i).get(key).equalsIgnoreCase(item))
{
return i;
}
}
return -1;
}
and call
int x = getItemPos("item" , "pen");
I have simply added products in the same ArrayList and then used for-loop to find that product position.
ArrayList<Products> mArrayList = new ArrayList<>();
Products products1 = new Products("2016-10-05", "Pens");
Products products2 = new Products("2016-10-04", "Pencil");
Products products3 = new Products("2016-10-03", "Book");
Products products4 = new Products("2016-10-02", "Dairy");
mArrayList.add(products1);
mArrayList.add(products2);
mArrayList.add(products3);
mArrayList.add(products4);
for (Products products : mArrayList) {
if (products.getitem().equals("Pens")) {
Log.d("Position", mArrayList.indexOf(products) + "");
}
}
This will give Output as
D/Position: 0
Example:
d1 = "the sky is blue"
d2 = "the car is blue"
Key Value
the [<d1,1>,<d2,1>]
sky [<d1,1>]
is [<d1,1>,<d2,1>]
blue [<d1,1>,<d2,1>]
car [<d2,1>]
Where:
key = String
ex:
<d1,1>
d1 = Document id
1 = How many times the word apear on file
I created a document type object with the docid variables and frequency.
public class Documento {
private final int docid;
private final int frequencia;
public Documento(int docid, int frequencia) {
this.docid = docid;
this.frequencia = frequencia;
}
public int getDocid() {
return docid;
}
public int getFrequencia() {
return frequencia;
}
#Override
public boolean equals(Object o) {
if ((o instanceof Documento) && docid == ((Documento) o).docid && frequencia == ((Documento) o).frequencia) {
return true;
}
return false;
}
And the dictionary class that is a hashmap with
public class Dicionario {
public Map<String, Documento> indice = new HashMap<>();
public void InsereDicionario(String palavra, int docid) {
int cont = indice.containsKey(palavra) ? indice.get(palavra).getFrequencia() : 0;
indice.put(palavra, new Documento(docid, cont + 1));
}
public int frequencia(String palavra) {
return indice.get(palavra).getFrequencia();
}
public void criaDicionario(String entrada) {
String[] palavras = entrada.split("\\s+");
for (int i = 0; i < palavras.length; i++) {
InsereDicionario(palavras[i], 1);
}
}
public void ListaPalavras(){
for(String key:indice.keySet()){
System.out.println("");
}
}
But what I really need the dictionary is a list of documents , and I do not know how to do this , someone could help me ?
or is there an easier way to do this ?
If you need a list of documents, why not create one? With Java8 this becomes even more convenient:
For example:
public Map<String, List<Documento>> indice = new HashMap<>();
//register new word
indice.putIfAbsent(palavra, new ArrayList<>());
//add additional occurence
indice.get(palavra).add(documento);
//get frequency
int frequencia = indice.get(palavra)
.stream()
.map(d -> d.getFrequencia())
.reduce(0, (s, i) -> s + i);
An alternative would be to use Guava's Multimap, see here
Map<String, List<Documento>>
Obviously you need to adapt the rest of the code.
For example, when you need to add something to the dictionary, if it's the first time you need to create the List with that single document, next time you need to take the already created list and add documents there.
i have a string array consisting of a name and a score. I want to sort that array by score. Problem is, considering it's a string array, the scores are strings which results in 13,16,2,5,6 and not 2,5,6,13,16. I am using this code:
int spaceIndex;
String[][] scoreboard;
String[] playername;
String[] score;
int sbsize;
array1.add("Thomas" + ":" + 5);
array1.add("Blueb" + ":" + 6);
array1.add("James" + ":" + 16);
array1.add("Hleb" + ":" + 13);
array1.add("Sabbat" + ":" + 2);
sbsize = array1.size();
scoreboard = new String[sbsize][2];
playername = new String[sbsize];
score = new String[sbsize];
pos2 = new int[sbsize];
for (int i=0; i<array1.size(); i++)
{
spaceIndex = array1.get(i).indexOf(':');
scoreboard[i][0] = array1.get(i).substring(0, spaceIndex);
scoreboard[i][1] = array1.get(i).substring(spaceIndex+1, array1.get(i).length());
}
Arrays.sort(scoreboard, new Comparator<String[]>() {
#Override
public int compare(String[] entry1, String[] entry2) {
String time1 = entry1[1];
String time2 = entry2[1];
return time1.compareTo(time2);
}
});
What is the solution?
Cast them to int. As I recall, something like...
Arrays.sort(scoreboard, new Comparator<String[]>() {
#Override
public int compare(String[] entry1, String[] entry2) {
Integer time1 = Integer.valueOf(entry1[1]);
Integer time2 = Integer.valueOf(entry2[1]);
return time1.compareTo(time2);
}
});
Also you can make simple value object class for easier manipulations. Like...
class Player
{
public String name;
public int score;
}
And after that you can make
Player[] scoreboard = ...
Arrays.sort(scoreboard, new Comparator<Player>() {
#Override
public int compare(Player player1, Player player2) {
if(player1.score > player2.score) return 1;
else if(player1.score < player2.score) return -1;
else return 0;
}
});
Edit:
I recommend you to understand the basic OOP principles, this will help you a lot in the beginning.
Edit 2: Java 8 (with functional interface and a lambda):
Arrays.sort(scoreboard, (player1, player2) -> {
Integer time1 = Integer.valueOf(player1[1]);
Integer time2 = Integer.valueOf(player2[1]);
return time1.compareTo(time2);
});
This is the easy way of Sorting String Array:
Arrays.sort(mystringarray);
Use
java.util.Arrays.sort(yourArray, new Comparator<String>() {
#Override
public int compare(String object1, String object2) {
return Integer.valueOf(object1).compareTo(Integer.valueOf(object2));
}
});
Comparator will compare your strings as integers.
ArrayList<String> names= new ArrayList<String>();
names.add("sathish");
names.add("Ravi");
names.add("Praksh");
names.add("pavithara");
names.add("Duraga");
names.add("uma");
names.add("Upendar");
System.out.println("Before sorting");
System.out.println("Names : "+names);
Collections.sort(names, new Comparator<String>() {
#Override
public int compare(String lhs, String rhs) {
return lhs.compareToIgnoreCase(rhs);//Ascending order.
//return (lhs.compareToIgnoreCase(rhs)*(-1));//Descending order.
}
});
System.out.println("After sorting");
System.out.println("Names : "+names);
output:
Before sorting
Names : [sathish, Ravi, Praksh, pavithara, Duraga, uma, Upendar]
After sorting
Names : [Duraga, pavithara, Praksh, Ravi, sathish, uma, Upendar]
If possible use better data structure for your problem, use HashMap, with name to score mapping and , sort the hashmap with values.
If you want to go with arraylist as described by you, before sorting, convert them into integer and sort, then back to string.
You would probably be better off storing the names + results in objects, then storing those in an ArrayList. You can then sort very easily using a custom comparator, see the link for a simple example: http://www.javabeat.net/tips/20-sorting-custom-types-in-java.html
Score should be a class like
public class HighScore Comparable<HighScore>
{
private String name;
private int score;
public Score( String name, int score )
{
this.name = name;
this.score = score;
}//cons
//getters
public String getName() {
return name;
}//met
public int getScore() {
return score;
}//met
#Override
public int compareTo( HighScrore b )
{
int diffScore = score - b.score;
if( diffScore != 0)
return diffScore;
else
return name.compareTo( b.name );
}//met
public boolean equals( Object o )
{
if( !(o instanceof HighScore))
return false;
HighScore b = (HighScore) o;
return score == b.score && name.equals( b.name );
}//met
}//class
Then you can build score objects,
String[] stringParts[];
List<HighScore> listHighScore = new ArrayList<HighScore>();
for (int i=0; i<array1.size(); i++)
{
stringParts = array1.get(i).split(':');
listHighScore.add( new HighScore( stringParts[ 0 ], Integer.parseInt( stringParts[ 1 ])) );
}//for
put them in a List and sort them through
Collections.sort( list );
Regards,
Stéphane
You can use ArrayList instead of Array.
Please check this link